<pre style='margin:0'>
ra1nb0w (ra1nb0w) pushed a commit to branch master
in repository macports-ports.
</pre>
<p><a href="https://github.com/macports/macports-ports/commit/e629dba7b3f9d67eab35a22d0139b2cd5ba2de16">https://github.com/macports/macports-ports/commit/e629dba7b3f9d67eab35a22d0139b2cd5ba2de16</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new e629dba gqrx-devel: update commit to ca0a615
</span>e629dba is described below
<span style='display:block; white-space:pre;color:#808000;'>commit e629dba7b3f9d67eab35a22d0139b2cd5ba2de16
</span>Author: Davide Gerhard <ra1nb0w@macports.org>
AuthorDate: Sat Apr 18 09:04:07 2020 +0200
<span style='display:block; white-space:pre;color:#404040;'> gqrx-devel: update commit to ca0a615
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> - add experimental variant with out-of-tree features
</span>---
science/gqrx/Portfile | 27 +-
science/gqrx/files/experimental.patch | 4541 +++++++++++++++++++++++++++++++++
2 files changed, 4562 insertions(+), 6 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/science/gqrx/Portfile b/science/gqrx/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index c60b1c2..06fde93 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/science/gqrx/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/science/gqrx/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -35,17 +35,32 @@ if {${subport} eq ${name}} {
</span>
subport gqrx-devel {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- github.setup csete gqrx 7f0c1d92f5de3a52d778004001be6f0d5d5d96f7
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- version 20200222-[string range ${github.version} 0 7]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- checksums rmd160 b5780a0ba2fdf41cec4225a374d03f3a1786d2ef \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- sha256 1613dfadc0e13235a2d7c6cae2f526b1ad48d47243b480303ac714e57b32c0d1 \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- size 1336002
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- revision 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ name gqrx-devel
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ github.setup csete gqrx ca0a6154620ac1a8c232241d52a2ffaa0ef9a9a5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ version 20200416-[string range ${github.version} 0 7]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ checksums rmd160 14939c0c127511bb9b1c340f56ff0985a8b84475 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sha256 6940abe572e3d9de8f6118783a7918c08c9305ce020771f165888882e0c84206 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ size 1338132
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ revision 0
</span>
long_description ${long_description} \
This port is kept up with the Gqrx GIT 'master' branch, is \
typically updated weekly to monthly.
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ variant experimental description "add experimental features to ${name}" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ patchfiles-append \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ experimental.patch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ notes {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+The experimental variant enable the following features:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- add Band Plan to bottom of FFT (see https://github.com/csete/gqrx/pull/767)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- pressing F moves focus to frequency widget
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- add support for DX Cluster server
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- improved noise blankers
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- implement DDC using a frequency xlating FIR filter
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> }
compiler.c_standard 2011
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/science/gqrx/files/experimental.patch b/science/gqrx/files/experimental.patch
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..3574534
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/science/gqrx/files/experimental.patch
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,4541 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git gqrx.pro gqrx.pro
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index d68723f..00ad537 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- gqrx.pro
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ gqrx.pro
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -121,6 +121,7 @@ SOURCES += \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/afsk1200win.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/agc_options.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/audio_options.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/bandplan.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/bookmarks.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/bookmarkstablemodel.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/bookmarkstaglist.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -141,7 +142,9 @@ SOURCES += \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/qtcolorpicker.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/receivers/nbrx.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/receivers/receiver_base.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- src/receivers/wfmrx.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/receivers/wfmrx.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/dxc_spots.cpp \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/dxc_options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ HEADERS += \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/applications/gqrx/gqrx.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -179,6 +182,7 @@ HEADERS += \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/afsk1200win.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/agc_options.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/audio_options.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/bandplan.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/bookmarks.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/bookmarkstablemodel.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/bookmarkstaglist.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -200,7 +204,9 @@ HEADERS += \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/qtcolorpicker.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/receivers/nbrx.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/receivers/receiver_base.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- src/receivers/wfmrx.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/receivers/wfmrx.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/dxc_spots.h \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/dxc_options.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ FORMS += \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/applications/gqrx/mainwindow.ui \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -217,7 +223,8 @@ FORMS += \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/iq_tool.ui \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/dockrxopt.ui \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ src/qtgui/ioconfig.ui \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- src/qtgui/nb_options.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/nb_options.ui \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src/qtgui/dxc_options.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Use pulseaudio (ps: could use equals? undocumented)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ equals(AUDIO_BACKEND, "pulseaudio"): {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/applications/gqrx/mainwindow.cpp src/applications/gqrx/mainwindow.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index b6e9407..d90034c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/applications/gqrx/mainwindow.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/applications/gqrx/mainwindow.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -48,6 +48,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <QSvgWidget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "qtgui/ioconfig.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "mainwindow.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "qtgui/dxc_spots.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Qt Designer files */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "ui_mainwindow.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -57,6 +58,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "remote_control_settings.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "qtgui/bookmarkstaglist.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "qtgui/bandplan.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ MainWindow::MainWindow(const QString cfgfile, bool edit_conf, QWidget *parent) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QMainWindow(parent),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -69,7 +71,9 @@ MainWindow::MainWindow(const QString cfgfile, bool edit_conf, QWidget *parent) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dec_afsk1200(0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->setupUi(this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BandPlan::create();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Bookmarks::create();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpots::create();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Initialise default configuration directory */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QByteArray xdg_dir = qgetenv("XDG_CONFIG_HOME");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -122,13 +126,20 @@ MainWindow::MainWindow(const QString cfgfile, bool edit_conf, QWidget *parent) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // create I/Q tool widget
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ iq_tool = new CIqTool(this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // create DXC Objects
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_options = new DXC_Options(this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_timer = new QTimer(this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_timer->start(1000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* create dock widgets */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockRxOpt = new DockRxOpt();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockRDS = new DockRDS();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockAudio = new DockAudio();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockInputCtl = new DockInputCtl();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockFft = new DockFft();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BandPlan::Get().setConfigDir(m_cfg_dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ Bookmarks::Get().setConfigDir(m_cfg_dir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BandPlan::Get().load();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockBookmarks = new DockBookmarks(this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // setup some toggle view shortcuts
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -236,6 +247,7 @@ MainWindow::MainWindow(const QString cfgfile, bool edit_conf, QWidget *parent) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(uiDockFft, SIGNAL(resetFftZoom()), ui->plotter, SLOT(resetHorizontalZoom()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(uiDockFft, SIGNAL(gotoFftCenter()), ui->plotter, SLOT(moveToCenterFreq()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(uiDockFft, SIGNAL(gotoDemodFreq()), ui->plotter, SLOT(moveToDemodFreq()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(uiDockFft, SIGNAL(bandPlanChanged(bool)), ui->plotter, SLOT(toggleBandPlan(bool)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(uiDockFft, SIGNAL(wfColormapChanged(const QString)), ui->plotter, SLOT(setWfColormap(const QString)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(uiDockFft, SIGNAL(wfColormapChanged(const QString)), uiDockAudio, SLOT(setWfColormap(const QString)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -259,6 +271,9 @@ MainWindow::MainWindow(const QString cfgfile, bool edit_conf, QWidget *parent) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(uiDockBookmarks, SIGNAL(newBookmarkActivated(qint64, QString, int)), this, SLOT(onBookmarkActivated(qint64, QString, int)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(uiDockBookmarks->actionAddBookmark, SIGNAL(triggered()), this, SLOT(on_actionAddBookmark_triggered()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //DXC Spots
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(&DXCSpots::Get(), SIGNAL(DXCSpotsChanged()),this , SLOT(addClusterSpot()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(dxc_timer, SIGNAL(timeout()), this, SLOT(checkDXCSpotTimeout()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // I/Q playback
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(iq_tool, SIGNAL(startRecording(QString)), this, SLOT(startIqRecording(QString)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -348,6 +363,9 @@ MainWindow::~MainWindow()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ audio_fft_timer->stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ delete audio_fft_timer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_timer->stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ delete dxc_timer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (m_settings)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_settings->setValue("configversion", 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -370,6 +388,7 @@ MainWindow::~MainWindow()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ delete iq_tool;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ delete dxc_options;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ delete ui;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ delete uiDockRxOpt;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ delete uiDockAudio;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -591,6 +610,7 @@ bool MainWindow::loadConfig(const QString cfgfile, bool check_crash,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockRxOpt->readSettings(m_settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockFft->readSettings(m_settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ uiDockAudio->readSettings(m_settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_options->readSettings(m_settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int64_val = m_settings->value("input/frequency", 14236000).toLongLong(&conv_ok);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -710,6 +730,7 @@ void MainWindow::storeSession()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ remote->saveSettings(m_settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ iq_tool->saveSettings(m_settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_options->saveSettings(m_settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int flo, fhi;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2056,6 +2077,11 @@ void MainWindow::afsk1200win_closed()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dec_afsk1200 = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Show DXC Options. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void MainWindow::on_actionDX_Cluster_triggered()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_options->show();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Cyclic processing for acquiring samples from receiver and processing them
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -2335,3 +2361,24 @@ void MainWindow::on_actionAddBookmark_triggered()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->plotter->updateOverlay();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void MainWindow::keyPressEvent(QKeyEvent *event)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ switch (event->key())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case Qt::Key_F:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->freqCtrl->setFrequencyFocus();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void MainWindow::addClusterSpot()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->plotter->updateOverlay();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void MainWindow::checkDXCSpotTimeout()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpots::Get().checkSpotTimeout();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->plotter->updateOverlay();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/applications/gqrx/mainwindow.h src/applications/gqrx/mainwindow.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index de45c6b..c7b99d1 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/applications/gqrx/mainwindow.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/applications/gqrx/mainwindow.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -32,6 +32,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <QMessageBox>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <QFileDialog>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <QSvgWidget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QKeyEvent>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "qtgui/dockrxopt.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "qtgui/dockaudio.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -41,6 +42,8 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "qtgui/dockrds.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "qtgui/afsk1200win.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "qtgui/iq_tool.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "qtgui/dxc_options.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "qtgui/dxc_spots.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "applications/gqrx/remote_control.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -99,6 +102,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ DockRDS *uiDockRDS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ CIqTool *iq_tool;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXC_Options *dxc_options;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* data decoders */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -110,6 +114,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QTimer *iq_fft_timer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QTimer *audio_fft_timer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QTimer *rds_timer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QTimer *dxc_timer;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ receiver *rx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -120,6 +125,9 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // dummy widget to enforce linking to QtSvg
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QSvgWidget *qsvg_dummy;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++protected:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void keyPressEvent(QKeyEvent *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void updateHWFrequencyRange(bool ignore_limits);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void updateFrequencyRange();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -201,6 +209,9 @@ private slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Bookmarks */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void onBookmarkActivated(qint64 freq, QString demod, int bandwidth);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* DXC Spots */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void addClusterSpot();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* menu and toolbar actions */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_actionDSP_triggered(bool checked);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int on_actionIoConfig_triggered();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -218,6 +229,7 @@ private slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_actionAbout_triggered();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_actionAboutQt_triggered();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_actionAddBookmark_triggered();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void on_actionDX_Cluster_triggered();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* window close signals */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -230,6 +242,7 @@ private slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void iqFftTimeout();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void audioFftTimeout();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void rdsTimeout();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void checkDXCSpotTimeout();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif // MAINWINDOW_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/applications/gqrx/mainwindow.ui src/applications/gqrx/mainwindow.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0fb1f36..dc39a81 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/applications/gqrx/mainwindow.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/applications/gqrx/mainwindow.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -195,7 +195,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <x>0</x>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <y>0</y>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <width>521</width>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- <height>19</height>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <height>22</height>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </rect>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <widget class="QMenu" name="menu_File">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -242,6 +242,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <addaction name="separator"/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <addaction name="actionAFSK1200"/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <addaction name="separator"/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <addaction name="actionDX_Cluster"/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <addaction name="menu_File"/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <addaction name="menu_Tools"/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -541,6 +542,17 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <string>Ctrl+W</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </action>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <action name="actionDX_Cluster">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>DX Cluster</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="toolTip">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Open DX Cluster Dialog</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="shortcut">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Ctrl+C</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </action>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <layoutdefault spacing="6" margin="11"/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <customwidgets>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/applications/gqrx/receiver.cpp src/applications/gqrx/receiver.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 4114b08..9406cba 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/applications/gqrx/receiver.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/applications/gqrx/receiver.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -50,6 +50,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define DEFAULT_AUDIO_GAIN -6.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define TARGET_QUAD_RATE 1e6
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * @brief Public contructor.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -103,19 +104,21 @@ receiver::receiver(const std::string input_device,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_decim = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_quad_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_quad_rate = d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim_rate = d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_ddc_decim = std::max(1, (int)(d_decim_rate / TARGET_QUAD_RATE));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_decim_rate / d_ddc_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ddc = make_downconverter_cc(d_ddc_decim, 0.0, d_decim_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx = make_nbrx(d_quad_rate, d_audio_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- rot = gr::blocks::rotator_cc::make(0.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ iq_swap = make_iq_swap_cc(false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- dc_corr = make_dc_corr_cc(d_quad_rate, 1.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- iq_fft = make_rx_fft_c(8192u, d_quad_rate, gr::filter::firdes::WIN_HANN);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dc_corr = make_dc_corr_cc(d_decim_rate, 1.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_fft = make_rx_fft_c(8192u, d_decim_rate, gr::filter::firdes::WIN_HANN);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ audio_fft = make_rx_fft_f(8192u, gr::filter::firdes::WIN_HANN);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ audio_gain0 = gr::blocks::multiply_const_ff::make(0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -351,11 +354,13 @@ double receiver::set_input_rate(double rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_input_rate = rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_quad_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- dc_corr->set_sample_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_ddc_decim = std::max(1, (int)(d_decim_rate / TARGET_QUAD_RATE));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_decim_rate / d_ddc_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dc_corr->set_sample_rate(d_decim_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ddc->set_decim_and_samp_rate(d_ddc_decim, d_decim_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ iq_fft->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -399,18 +404,20 @@ unsigned int receiver::set_input_decim(unsigned int decim)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_decim = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_quad_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_quad_rate = d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim_rate = d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // update quadrature rate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- dc_corr->set_sample_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_ddc_decim = std::max(1, (int)(d_decim_rate / TARGET_QUAD_RATE));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_decim_rate / d_ddc_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dc_corr->set_sample_rate(d_decim_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ddc->set_decim_and_samp_rate(d_ddc_decim, d_decim_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ iq_fft->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -424,7 +431,7 @@ unsigned int receiver::set_input_decim(unsigned int decim)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef CUSTOM_AIRSPY_KERNELS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (input_devstr.find("airspy") != std::string::npos)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- src->set_bandwidth(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_bandwidth(d_decim_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -648,7 +655,7 @@ receiver::status receiver::set_auto_gain(bool automatic)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ receiver::status receiver::set_filter_offset(double offset_hz)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_filter_offset = offset_hz;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ddc->set_center_freq(d_filter_offset - d_cw_offset);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -667,7 +674,7 @@ double receiver::get_filter_offset(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ receiver::status receiver::set_cw_offset(double offset_hz)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_cw_offset = offset_hz;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ddc->set_center_freq(d_filter_offset - d_cw_offset);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx->set_cw_offset(d_cw_offset);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1329,8 +1336,8 @@ void receiver::connect_all(rx_chain type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // Audio path (if there is a receiver)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (type != RX_CHAIN_NONE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- tb->connect(b, 0, rot, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- tb->connect(rot, 0, rx, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(b, 0, ddc, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(ddc, 0, rx, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tb->connect(rx, 0, audio_fft, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tb->connect(rx, 0, audio_udp_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tb->connect(rx, 1, audio_udp_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1354,12 +1361,6 @@ void receiver::connect_all(rx_chain type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-/** Convenience function to update all DDC related components. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-void receiver::update_ddc()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- rot->set_phase_inc(2.0 * M_PI * (-d_filter_offset + d_cw_offset) / d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void receiver::get_rds_data(std::string &outbuff, int &num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx->get_rds_data(outbuff, num);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/applications/gqrx/receiver.cpp.orig src/applications/gqrx/receiver.cpp.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..4114b08
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/applications/gqrx/receiver.cpp.orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,1390 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * http://gqrx.dk/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2011-2014 Alexandru Csete OZ9AEC.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with Gqrx; see the file COPYING. If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <cmath>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <iostream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef _MSC_VER
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <iostream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/prefs.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/top_block.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <osmosdr/source.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <osmosdr/ranges.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "applications/gqrx/receiver.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dsp/correct_iq_cc.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++//#include "dsp/hbf_decim.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dsp/filter/fir_decim.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dsp/rx_fft.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "receivers/nbrx.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "receivers/wfmrx.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef WITH_PULSEAUDIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "pulseaudio/pa_sink.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#elif WITH_PORTAUDIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "portaudio/portaudio_sink.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/audio/sink.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define DEFAULT_AUDIO_GAIN -6.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Public contructor.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param input_device Input device specifier.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param audio_device Audio output device specifier,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * e.g. hw:0 when using ALSA or Portaudio.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::receiver(const std::string input_device,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const std::string audio_device,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int decimation)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ : d_running(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_input_rate(96000.0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_audio_rate(48000),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim(decimation),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_rf_freq(144800000.0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_filter_offset(0.0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_cw_offset(0.0),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_recording_iq(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_recording_wav(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_sniffer_active(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_iq_rev(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_dc_cancel(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_iq_balance(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_demod(RX_DEMOD_OFF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb = gr::make_top_block("gqrx");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (input_device.empty())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src = osmosdr::source::make("file="+get_random_file()+",freq=428e6,rate=96000,repeat=true,throttle=true");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ input_devstr = input_device;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src = osmosdr::source::make(input_device);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // input decimator
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ try
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ input_decim = make_fir_decim_cc(d_decim);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ catch (std::range_error &e)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Error creating input decimator " << d_decim
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << ": " << e.what() << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << "Using decimation 1." << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx = make_nbrx(d_quad_rate, d_audio_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rot = gr::blocks::rotator_cc::make(0.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_swap = make_iq_swap_cc(false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dc_corr = make_dc_corr_cc(d_quad_rate, 1.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_fft = make_rx_fft_c(8192u, d_quad_rate, gr::filter::firdes::WIN_HANN);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_fft = make_rx_fft_f(8192u, gr::filter::firdes::WIN_HANN);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_gain0 = gr::blocks::multiply_const_ff::make(0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_gain1 = gr::blocks::multiply_const_ff::make(0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ set_af_gain(DEFAULT_AUDIO_GAIN);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_udp_sink = make_udp_sink_f();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef WITH_PULSEAUDIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_snk = make_pa_sink(audio_device, d_audio_rate, "GQRX", "Audio output");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#elif WITH_PORTAUDIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_snk = make_portaudio_sink(audio_device, d_audio_rate, "GQRX", "Audio output");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_snk = gr::audio::sink::make(d_audio_rate, audio_device, true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ output_devstr = audio_device;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* wav sink and source is created when rec/play is started */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_null_sink0 = gr::blocks::null_sink::make(sizeof(float));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_null_sink1 = gr::blocks::null_sink::make(sizeof(float));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sniffer = make_sniffer_f();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* sniffer_rr is created at each activation. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ set_demod(RX_DEMOD_NFM);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef QT_NO_DEBUG_OUTPUT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::prefs pref;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Using audio backend: "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << pref.get_string("audio", "audio_module", "N/A")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::~receiver()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Start the receiver. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::start()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_running = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Stop the receiver. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::stop()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->wait(); // If the graph is needed to run again, wait() must be called after stop
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_running = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Select new input device.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @bug When using ALSA, program will crash if the new device
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * is the same as the previously used device:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * audio_alsa_source[hw:1]: Device or resource busy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_input_device(const std::string device)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::string error = "";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (device.empty())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (input_devstr.compare(device) == 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef QT_NO_DEBUG_OUTPUT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "No change in input device:" << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << " old: " << input_devstr << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << " new: " << device << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ input_devstr = device;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // tb->lock() can hang occasionally
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->wait();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(src, 0, input_decim, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(input_decim, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(src, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ try
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src = osmosdr::source::make(device);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ catch (std::runtime_error &x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ error = x.what();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src = osmosdr::source::make("file="+get_random_file()+",freq=428e6,rate=96000,repeat=true,throttle=true");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(src->get_sample_rate() != 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ set_input_rate(src->get_sample_rate());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(src, 0, input_decim, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(input_decim, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(src, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (error != "")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ throw std::runtime_error(error);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Select new audio output device. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_output_device(const std::string device)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (output_devstr.compare(device) == 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef QT_NO_DEBUG_OUTPUT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "No change in output device:" << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << " old: " << output_devstr << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << " new: " << device << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef QT_NO_DEBUG_OUTPUT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "New audio output device:" << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << " old: " << output_devstr << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << " new: " << device << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ output_devstr = device;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_demod != RX_DEMOD_OFF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(audio_gain0, 0, audio_snk, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(audio_gain1, 0, audio_snk, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_snk.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef WITH_PULSEAUDIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_snk = make_pa_sink(device, d_audio_rate, "GQRX", "Audio output");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#elif WITH_PORTAUDIO
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_snk = make_portaudio_sink(device, d_audio_rate, "GQRX", "Audio output");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_snk = gr::audio::sink::make(d_audio_rate, device, true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_demod != RX_DEMOD_OFF)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(audio_gain0, 0, audio_snk, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(audio_gain1, 0, audio_snk, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Get a list of available antenna connectors. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector<std::string> receiver::get_antennas(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return src->get_antennas();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Select antenna conenctor. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_antenna(const std::string &antenna)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!antenna.empty())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_antenna(antenna);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Set new input sample rate.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param rate The desired input rate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return The actual sample rate set or 0 if there was an error with the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * device.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double receiver::set_input_rate(double rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double current_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool rate_has_changed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ current_rate = src->get_sample_rate();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rate_has_changed = !(rate == current_rate ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::abs(rate - current_rate) < std::abs(std::min(rate, current_rate))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * std::numeric_limits<double>::epsilon());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_input_rate = src->set_sample_rate(rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_input_rate == 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // This can be the case when no device is attached and gr-osmosdr
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // puts in a null_source with rate 100 ksps or if the rate has not
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // changed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rate_has_changed)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cerr << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cerr << "Failed to set RX input rate to " << rate << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cerr << "Your device may not be working properly." << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cerr << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_input_rate = rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dc_corr->set_sample_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_fft->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set input decimation */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++unsigned int receiver::set_input_decim(unsigned int decim)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (decim == d_decim)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->wait();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(src, 0, input_decim, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(input_decim, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(src, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ input_decim.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim = decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ try
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ input_decim = make_fir_decim_cc(d_decim);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ catch (std::range_error &e)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Error opening creating input decimator " << d_decim
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << ": " << e.what() << std::endl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ << "Using decimation 1." << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_input_rate / (double)d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_quad_rate = d_input_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // update quadrature rate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dc_corr->set_sample_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_fft->set_quad_rate(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(src, 0, input_decim, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(input_decim, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(src, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifdef CUSTOM_AIRSPY_KERNELS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (input_devstr.find("airspy") != std::string::npos)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_bandwidth(d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Set new analog bandwidth.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param bw The new bandwidth.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return The actual bandwidth.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double receiver::set_analog_bandwidth(double bw)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return src->set_bandwidth(bw);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Get current analog bandwidth. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double receiver::get_analog_bandwidth(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return src->get_bandwidth();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set I/Q reversed. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_iq_swap(bool reversed)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (reversed == d_iq_rev)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_iq_rev = reversed;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_swap->set_enabled(d_iq_rev);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get current I/Q reversed setting.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @retval true I/Q swappign is enabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @retval false I/Q swapping is disabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool receiver::get_iq_swap(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_iq_rev;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Enable/disable automatic DC removal in the I/Q stream.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param enable Whether DC removal should enabled or not.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_dc_cancel(bool enable)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (enable == d_dc_cancel)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_dc_cancel = enable;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // until we have a way to switch on/off
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // inside the dc_corr_cc we do a reconf
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx_demod demod = d_demod;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_demod = RX_DEMOD_OFF;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ set_demod(demod);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get auto DC cancel status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @retval true Automatic DC removal is enabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @retval false Automatic DC removal is disabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool receiver::get_dc_cancel(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_dc_cancel;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Enable/disable automatic I/Q balance.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param enable Whether automatic I/Q balance should be enabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_iq_balance(bool enable)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (enable == d_iq_balance)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_iq_balance = enable;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_iq_balance_mode(enable ? 2 : 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get auto I/Q balance status.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @retval true Automatic I/Q balance is enabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @retval false Automatic I/Q balance is disabled.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool receiver::get_iq_balance(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_iq_balance;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Set RF frequency.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param freq_hz The desired frequency in Hz.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return RX_STATUS_ERROR if an error occurs, e.g. the frequency is out of range.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @sa get_rf_freq()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_rf_freq(double freq_hz)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_rf_freq = freq_hz;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_center_freq(d_rf_freq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // FIXME: read back frequency?
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get RF frequency.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return The current RF frequency.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @sa set_rf_freq()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double receiver::get_rf_freq(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_rf_freq = src->get_center_freq();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_rf_freq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get the RF frequency range of the current input device.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param start The lower limit of the range in Hz.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param stop The upper limit of the range in Hz.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param step The frequency step in Hz.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @returns STATUS_OK if the range could be retrieved, STATUS_ERROR if an error has occurred.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::get_rf_range(double *start, double *stop, double *step)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ osmosdr::freq_range_t range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ range = src->get_freq_range();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // currently range is empty for all but E4000
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!range.empty())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (range.start() < range.stop())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *start = range.start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *stop = range.stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *step = range.step(); /** FIXME: got 0 for rtl-sdr? **/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Get the names of available gain stages. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++std::vector<std::string> receiver::get_gain_names()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return src->get_gain_names();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get gain range for a specific stage.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param[in] name The name of the gain stage.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param[out] start Lower limit for this gain setting.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param[out] stop Upper limit for this gain setting.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param[out] step The resolution for this gain setting.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This function retunrs the range for the requested gain stage.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::get_gain_range(std::string &name, double *start,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double *stop, double *step) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ osmosdr::gain_range_t range;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ range = src->get_gain_range(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *start = range.start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *stop = range.stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *step = range.step();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_gain(std::string name, double value)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_gain(value, name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double receiver::get_gain(std::string name) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return src->get_gain(name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Set RF gain.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param gain_rel The desired relative gain between 0.0 and 1.0 (use -1 for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * AGC where supported).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return RX_STATUS_ERROR if an error occurs, e.g. the gain is out of valid range.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_auto_gain(bool automatic)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_gain_mode(automatic);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Set filter offset.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param offset_hz The desired filter offset in Hz.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return RX_STATUS_ERROR if the tuning offset is out of range.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This method sets a new tuning offset for the receiver. The tuning offset is used
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * to tune within the passband, i.e. select a specific channel within the received
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * spectrum.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * The valid range for the tuning is +/- 0.5 * the bandwidth although this is just a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * logical limit.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @sa get_filter_offset()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_filter_offset(double offset_hz)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_filter_offset = offset_hz;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get filter offset.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return The current filter offset.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @sa set_filter_offset()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double receiver::get_filter_offset(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_filter_offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* CW offset can serve as a "BFO" if the GUI needs it */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_cw_offset(double offset_hz)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_cw_offset = offset_hz;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_cw_offset(d_cw_offset);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double receiver::get_cw_offset(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_cw_offset;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_filter(double low, double high, filter_shape shape)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double trans_width;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ((low >= high) || (std::abs(high-low) < RX_FILTER_MIN_WIDTH))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ switch (shape) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case FILTER_SHAPE_SOFT:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ trans_width = std::abs(high - low) * 0.5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case FILTER_SHAPE_SHARP:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ trans_width = std::abs(high - low) * 0.1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case FILTER_SHAPE_NORMAL:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ trans_width = std::abs(high - low) * 0.2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_filter(low, high, trans_width);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_freq_corr(double ppm)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ src->set_freq_corr(ppm);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Get current signal power.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param dbfs Whether to use dbfs or absolute power.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return The current signal power.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This method returns the current signal power detected by the receiver. The detector
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * is located after the band pass filter. The full scale is 1.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++float receiver::get_signal_pwr(bool dbfs) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return rx->get_signal_level(dbfs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set new FFT size. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_iq_fft_size(int newsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_fft->set_fft_size(newsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::set_iq_fft_window(int window_type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_fft->set_window_type(window_type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Get latest baseband FFT data. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::get_iq_fft_data(std::complex<float>* fftPoints, unsigned int &fftsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_fft->get_fft_data(fftPoints, fftsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Get latest audio FFT data. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::get_audio_fft_data(std::complex<float>* fftPoints, unsigned int &fftsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_fft->get_fft_data(fftPoints, fftsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_nb_on(int nbid, bool on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_nb())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_nb_on(nbid, on);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_nb_threshold(int nbid, float threshold)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_nb())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_nb_threshold(nbid, threshold);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Set squelch level.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param level_db The new level in dBFS.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_sql_level(double level_db)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_sql())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_sql_level(level_db);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set squelch alpha */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_sql_alpha(double alpha)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_sql())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_sql_alpha(alpha);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Enable/disable receiver AGC.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * When AGC is disabled a fixed manual gain is used, see set_agc_manual_gain().
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_agc_on(bool agc_on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_agc())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_agc_on(agc_on);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Enable/disable AGC hang. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_agc_hang(bool use_hang)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_agc())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_agc_hang(use_hang);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set AGC threshold. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_agc_threshold(int threshold)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_agc())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_agc_threshold(threshold);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set AGC slope. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_agc_slope(int slope)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_agc())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_agc_slope(slope);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set AGC decay time. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_agc_decay(int decay_ms)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_agc())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_agc_decay(decay_ms);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Set fixed gain used when AGC is OFF. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_agc_manual_gain(int gain)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_agc())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_agc_manual_gain(gain);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK; // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_demod(rx_demod demod)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ status ret = STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Allow reconf using same demod to provide a workaround
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // for the "jerky streaming" we may experience with rtl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // dongles (the jerkyness disappears when we run this function)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //if (demod == d_demod)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // tb->lock() seems to hang occasioanlly
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->wait();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect_all();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ switch (demod)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_OFF:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_NONE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_NONE:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_NBRX);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_demod(nbrx::NBRX_DEMOD_NONE);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_AM:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_NBRX);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_demod(nbrx::NBRX_DEMOD_AM);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_NFM:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_NBRX);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_demod(nbrx::NBRX_DEMOD_FM);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_WFM_M:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_WFMRX);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_demod(wfmrx::WFMRX_DEMOD_MONO);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_WFM_S:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_WFMRX);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_demod(wfmrx::WFMRX_DEMOD_STEREO);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_WFM_S_OIRT:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_WFMRX);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_demod(wfmrx::WFMRX_DEMOD_STEREO_UKW);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_DEMOD_SSB:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all(RX_CHAIN_NBRX);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_demod(nbrx::NBRX_DEMOD_SSB);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ret = STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_demod = demod;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Set maximum deviation of the FM demodulator.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param maxdev_hz The new maximum deviation in Hz.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_fm_maxdev(float maxdev_hz)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_fm())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_fm_maxdev(maxdev_hz);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_fm_deemph(double tau)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_fm())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_fm_deemph(tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_am_dcr(bool enabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->has_am())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->set_am_dcr(enabled);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::set_af_gain(float gain_db)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ float k;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* convert dB to factor */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ k = pow(10.0, gain_db / 20.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //std::cout << "G:" << gain_db << "dB / K:" << k << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_gain0->set_k(k);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_gain1->set_k(k);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Start WAV file recorder.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param filename The filename where to record.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * A new recorder object is created every time we start recording and deleted every time
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * we stop recording. The idea of creating one object and starting/stopping using different
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * file names does not work with WAV files (the initial /tmp/gqrx.wav will not be stopped
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * because the wav file can not be empty). See https://github.com/csete/gqrx/issues/36
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::start_audio_recording(const std::string filename)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_recording_wav)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* error - we are already recording */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "ERROR: Can not start audio recorder (already recording)" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* receiver is not running */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Can not start audio recorder (receiver not running)" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // if this fails, we don't want to go and crash now, do we
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ try {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wav_sink = gr::blocks::wavfile_sink::make(filename.c_str(), 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ (unsigned int) d_audio_rate,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 16);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ catch (std::runtime_error &e) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Error opening " << filename << ": " << e.what() << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, wav_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 1, wav_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_recording_wav = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Recording audio to " << filename << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Stop WAV file recorder. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::stop_audio_recording()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!d_recording_wav) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* error: we are not recording */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "ERROR: Can not stop audio recorder (not recording)" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* receiver is not running */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Can not stop audio recorder (receiver not running)" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // not strictly necessary to lock but I think it is safer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wav_sink->close();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 0, wav_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 1, wav_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wav_sink.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_recording_wav = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Audio recorder stopped" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Start audio playback. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::start_audio_playback(const std::string filename)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!d_running)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* receiver is not running */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Can not start audio playback (receiver not running)" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ try {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // output ports set automatically from file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wav_src = gr::blocks::wavfile_source::make(filename.c_str(), false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ catch (std::runtime_error &e) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Error loading " << filename << ": " << e.what() << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /** FIXME: We can only handle native rate (should maybe use the audio_rr)? */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int audio_rate = (unsigned int) d_audio_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (wav_src->sample_rate() != audio_rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "BUG: Can not handle sample rate " << wav_src->sample_rate() << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wav_src.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /** FIXME: We can only handle stereo files */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (wav_src->channels() != 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "BUG: Can not handle other than 2 channels. File has " << wav_src->channels() << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wav_src.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* route demodulator output to null sink */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 0, audio_gain0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 1, audio_gain1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 0, audio_fft, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 0, audio_udp_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 1, audio_udp_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, audio_null_sink0, 0); /** FIXME: other channel? */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 1, audio_null_sink1, 0); /** FIXME: other channel? */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(wav_src, 0, audio_gain0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(wav_src, 1, audio_gain1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(wav_src, 0, audio_fft, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(wav_src, 0, audio_udp_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(wav_src, 1, audio_udp_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << "Playing audio from " << filename << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Stop audio playback. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::stop_audio_playback()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* disconnect wav source and reconnect receiver */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(wav_src, 0, audio_gain0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(wav_src, 1, audio_gain1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(wav_src, 0, audio_fft, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(wav_src, 0, audio_udp_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(wav_src, 1, audio_udp_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 0, audio_null_sink0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 1, audio_null_sink1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, audio_gain0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 1, audio_gain1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, audio_fft, 0); /** FIXME: other channel? */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, audio_udp_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 1, audio_udp_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* delete wav_src since we can not change file name */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ wav_src.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Start UDP streaming of audio. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::start_udp_streaming(const std::string host, int port, bool stereo)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_udp_sink->start_streaming(host, port, stereo);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Stop UDP streaming of audio. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::stop_udp_streaming()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ audio_udp_sink->stop_streaming();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Start I/Q data recorder.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param filename The filename where to record.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::start_iq_recording(const std::string filename)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ receiver::status status = STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_recording_iq) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << __func__ << ": already recording" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ try
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_sink = gr::blocks::file_sink::make(sizeof(gr_complex), filename.c_str(), true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ catch (std::runtime_error &e)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::cout << __func__ << ": couldn't open I/Q file" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(input_decim, 0, iq_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(src, 0, iq_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_recording_iq = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return status;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Stop I/Q data recorder. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::stop_iq_recording()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!d_recording_iq) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* error: we are not recording */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_sink->close();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(input_decim, 0, iq_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(src, 0, iq_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ iq_sink.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_recording_iq = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Seek to position in IQ file source.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param pos Byte offset from the beginning of the file.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::seek_iq_file(long pos)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ receiver::status status = STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (src->seek(pos, SEEK_SET))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ status = STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ status = STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return status;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Start data sniffer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @param buffsize The buffer that should be used in the sniffer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return STATUS_OK if the sniffer was started, STATUS_ERROR if the sniffer is already in use.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::start_sniffer(unsigned int samprate, int buffsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_sniffer_active) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* sniffer already in use */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sniffer->set_buffer_size(buffsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sniffer_rr = make_resampler_ff((float)samprate/(float)d_audio_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, sniffer_rr, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(sniffer_rr, 0, sniffer, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_sniffer_active = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/**
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @brief Stop data sniffer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * @return STATUS_ERROR i the sniffer is not currently active.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++receiver::status receiver::stop_sniffer()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!d_sniffer_active) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_ERROR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(rx, 0, sniffer_rr, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->disconnect(sniffer_rr, 0, sniffer, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_sniffer_active = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ /* delete resampler */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sniffer_rr.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return STATUS_OK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Get sniffer data. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::get_sniffer_data(float * outbuff, unsigned int &num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sniffer->get_samples(outbuff, num);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Convenience function to connect all blocks. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::connect_all(rx_chain type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::basic_block_sptr b;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Setup source
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ b = src;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Pre-processing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim >= 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(b, 0, input_decim, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ b = input_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_recording_iq)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // We record IQ with minimal pre-processing
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(b, 0, iq_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(b, 0, iq_swap, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ b = iq_swap;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_dc_cancel)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(b, 0, dc_corr, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ b = dc_corr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Visualization
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(b, 0, iq_fft, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // RX demod chain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ switch (type)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_CHAIN_NBRX:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->name() != "NBRX")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx = make_nbrx(d_quad_rate, d_audio_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ case RX_CHAIN_WFMRX:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (rx->name() != "WFMRX")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx.reset();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx = make_wfmrx(d_quad_rate, d_audio_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ default:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Audio path (if there is a receiver)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (type != RX_CHAIN_NONE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(b, 0, rot, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rot, 0, rx, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, audio_fft, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, audio_udp_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 1, audio_udp_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, audio_gain0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 1, audio_gain1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(audio_gain0, 0, audio_snk, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(audio_gain1, 0, audio_snk, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Recorders and sniffers
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_recording_wav)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, wav_sink, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 1, wav_sink, 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_sniffer_active)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(rx, 0, sniffer_rr, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tb->connect(sniffer_rr, 0, sniffer, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/** Convenience function to update all DDC related components. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::update_ddc()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rot->set_phase_inc(2.0 * M_PI * (-d_filter_offset + d_cw_offset) / d_quad_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::get_rds_data(std::string &outbuff, int &num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->get_rds_data(outbuff, num);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::start_rds_decoder(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->start_rds_decoder();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::stop_rds_decoder(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ stop();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->stop_rds_decoder();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ start();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool receiver::is_rds_decoder_active(void) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return rx->is_rds_decoder_active();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void receiver::reset_rds_parser(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rx->reset_rds_parser();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/applications/gqrx/receiver.h src/applications/gqrx/receiver.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 109a80d..b577ae9 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/applications/gqrx/receiver.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/applications/gqrx/receiver.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -31,7 +31,6 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/blocks/file_sink.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/blocks/null_sink.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#include <gnuradio/blocks/rotator_cc.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/blocks/wavfile_sink.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/blocks/wavfile_source.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/top_block.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -39,6 +38,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "dsp/correct_iq_cc.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dsp/downconverter.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "dsp/filter/fir_decim.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "dsp/rx_noise_blanker_cc.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "dsp/rx_filter.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -226,14 +226,15 @@ public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void connect_all(rx_chain type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- void update_ddc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool d_running; /*!< Whether receiver is running or not. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ double d_input_rate; /*!< Input sample rate. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- double d_quad_rate; /*!< Quadrature rate (input_rate / decim) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_decim_rate; /*!< Rate after decimation (input_rate / decim) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_quad_rate; /*!< Quadrature rate (after down-conversion) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ double d_audio_rate; /*!< Audio output rate. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ unsigned int d_decim; /*!< input decimation. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int d_ddc_decim; /*!< Down-conversion decimation. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ double d_rf_freq; /*!< Current RF frequency. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ double d_filter_offset; /*!< Current filter offset */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ double d_cw_offset; /*!< CW offset */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -261,7 +262,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx_fft_c_sptr iq_fft; /*!< Baseband FFT block. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx_fft_f_sptr audio_fft; /*!< Audio FFT block. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- gr::blocks::rotator_cc::sptr rot; /*!< Rotator used when only shifting frequency */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ downconverter_cc_sptr ddc; /*!< Digital down-converter for demod chain. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr::blocks::multiply_const_ff::sptr audio_gain0; /*!< Audio gain block. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr::blocks::multiply_const_ff::sptr audio_gain1; /*!< Audio gain block. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/dsp/CMakeLists.txt src/dsp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index daae9fc..3e984e1 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/dsp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/dsp/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -22,6 +22,8 @@ add_source_files(SRCS_LIST
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ agc_impl.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ correct_iq_cc.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ correct_iq_cc.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ downconverter.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ downconverter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lpf.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lpf.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ resampler_xx.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/dsp/downconverter.cpp src/dsp/downconverter.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..dde591e
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/dsp/downconverter.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,106 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * http://gqrx.dk/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2020 Clayton Smith VE3IRR.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with Gqrx; see the file COPYING. If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <math.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/filter/firdes.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/io_signature.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "downconverter.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define LPF_CUTOFF 120e3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++downconverter_cc_sptr make_downconverter_cc(unsigned int decim, double center_freq, double samp_rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return gnuradio::get_initial_sptr(new downconverter_cc(decim, center_freq, samp_rate));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++downconverter_cc::downconverter_cc(unsigned int decim, double center_freq, double samp_rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ : gr::hier_block2("downconverter_cc",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::io_signature::make(1, 1, sizeof(gr_complex)),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::io_signature::make(1, 1, sizeof(gr_complex))),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim(decim),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_center_freq(center_freq),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_samp_rate(samp_rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_proto_taps();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_phase_inc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++downconverter_cc::~downconverter_cc()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void downconverter_cc::set_decim_and_samp_rate(unsigned int decim, double samp_rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_samp_rate = samp_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (decim != d_decim)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_decim = decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ lock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect_all();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect_all();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unlock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_proto_taps();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_phase_inc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void downconverter_cc::set_center_freq(double center_freq)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_center_freq = center_freq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ update_phase_inc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void downconverter_cc::connect_all()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim > 1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ filt = gr::filter::freq_xlating_fir_filter_ccf::make(d_decim, {1}, 0.0, d_samp_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(self(), 0, filt, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(filt, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rot = gr::blocks::rotator_cc::make(0.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(self(), 0, rot, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(rot, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void downconverter_cc::update_proto_taps()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim > 1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double out_rate = d_samp_rate / d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ filt->set_taps(gr::filter::firdes::low_pass(1.0, d_samp_rate, LPF_CUTOFF, out_rate - 2*LPF_CUTOFF));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void downconverter_cc::update_phase_inc()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_decim > 1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ filt->set_center_freq(d_center_freq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rot->set_phase_inc(-2.0 * M_PI * d_center_freq / d_samp_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/dsp/downconverter.h src/dsp/downconverter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..9c3b55a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/dsp/downconverter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,61 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * http://gqrx.dk/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2020 Clayton Smith VE3IRR.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with Gqrx; see the file COPYING. If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#pragma once
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if GNURADIO_VERSION < 0x030800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/filter/freq_xlating_fir_filter_ccf.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/filter/freq_xlating_fir_filter.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/blocks/rotator_cc.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/hier_block2.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class downconverter_cc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++typedef boost::shared_ptr<downconverter_cc> downconverter_cc_sptr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++downconverter_cc_sptr make_downconverter_cc(unsigned int decim, double center_freq, double samp_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class downconverter_cc : public gr::hier_block2
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ friend downconverter_cc_sptr make_downconverter_cc(unsigned int decim, double center_freq, double samp_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ downconverter_cc(unsigned int decim, double center_freq, double samp_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ~downconverter_cc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void set_decim_and_samp_rate(unsigned int decim, double samp_rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void set_center_freq(double center_freq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ unsigned int d_decim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_center_freq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_samp_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::vector<float> d_proto_taps;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void connect_all();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void update_proto_taps();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void update_phase_inc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::filter::freq_xlating_fir_filter_ccf::sptr filt;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::blocks::rotator_cc::sptr rot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/dsp/rx_noise_blanker_cc.cpp src/dsp/rx_noise_blanker_cc.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index c8e2447..ae9fd2b 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/dsp/rx_noise_blanker_cc.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/dsp/rx_noise_blanker_cc.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -26,6 +26,14 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/gr_complex.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "dsp/rx_noise_blanker_cc.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void rx_nb_cc::forecast (int noutput_items, gr_vector_int &ninput_items_required)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ninput_items_required[0] = d_nb2_bsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx_nb_cc_sptr make_rx_nb_cc(double sample_rate, float thld1, float thld2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return gnuradio::get_initial_sptr(new rx_nb_cc(sample_rate, thld1, thld2));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -38,8 +46,8 @@ rx_nb_cc_sptr make_rx_nb_cc(double sample_rate, float thld1, float thld2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx_nb_cc::rx_nb_cc(double sample_rate, float thld1, float thld2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ : gr::sync_block ("rx_nb_cc",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- gr::io_signature::make(1, 1, sizeof(gr_complex)),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- gr::io_signature::make(1, 1, sizeof(gr_complex))),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::io_signature::make(1, 1, sizeof(float)),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::io_signature::make(1, 1, sizeof(float))),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_nb1_on(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_nb2_on(false),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_sample_rate(sample_rate),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -52,10 +60,293 @@ rx_nb_cc::rx_nb_cc(double sample_rate, float thld1, float thld2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ d_hangtime(0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ memset(d_delay, 0, 8 * sizeof(gr_complex));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Init nb1 params
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_dline_size = 2048;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_mask = 2048 - 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_n_taps = 64;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_delay = 16;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_two_mu = 1.0e-4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_gamma = 0.1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_in_idx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_lidx = 120.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_lidx_min = 120.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_lidx_max = 200.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_ngamma = 0.001;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_den_mult = 6.25e-10;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_lincr = 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_ldecr = 3.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb1_d, 0, sizeof(double) * 2048);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb1_w, 0, sizeof(double) * 2048);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Init nb2 params
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_bsize = (int)1024;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_fsize = (int)4096;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ovrlp = 32;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_rate = (int)96000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ogain = 0.99;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // nb2 - initial setup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double Dvals[18] = { 1.0, 2.0, 5.0, 8.0, 10.0, 15.0, 20.0, 30.0, 40.0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 60.0, 80.0, 120.0, 140.0, 160.0, 180.0, 220.0, 260.0, 300.0 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double Mvals[18] = { 0.000, 0.260, 0.480, 0.580, 0.610, 0.668, 0.705, 0.762, 0.800,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0.841, 0.865, 0.890, 0.900, 0.910, 0.920, 0.930, 0.935, 0.940 };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double arg, sum, inv_coherent_gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_incr = (double)d_nb2_fsize / (double)d_nb2_ovrlp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_gain = (double)d_nb2_ogain / (double)d_nb2_fsize / (double)d_nb2_ovrlp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_fsize > d_nb2_bsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iasize = d_nb2_fsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iasize = d_nb2_bsize + d_nb2_fsize - d_nb2_incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iainidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iaoutidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_fsize > d_nb2_bsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_bsize > d_nb2_incr) d_nb2_oasize = d_nb2_bsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else d_nb2_oasize = d_nb2_incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oainidx = (d_nb2_fsize - d_nb2_bsize - d_nb2_incr) % d_nb2_oasize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oasize = d_nb2_bsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oainidx = d_nb2_fsize - d_nb2_incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_init_oainidx = d_nb2_oainidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oaoutidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_msize = d_nb2_fsize / 2 + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_window = (double *)malloc(d_nb2_fsize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_inaccum = (double *)malloc(d_nb2_iasize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_mask = (double *)malloc(d_nb2_msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_save = (double **)malloc(d_nb2_ovrlp * sizeof(double *));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_ovrlp; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_save[i] = (double *)malloc(d_nb2_fsize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_outaccum = (double *)malloc(d_nb2_oasize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nsamps = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_saveidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_fft1 = new gr::fft::fft_real_fwd(d_nb2_fsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_fft2 = new gr::fft::fft_real_rev(d_nb2_fsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ arg = 2.0 * 3.1415926 / (double)d_nb2_fsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_fsize; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_window[i] = sqrt (0.54 - 0.46 * cos((double)i * arg));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum += d_nb2_window[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ inv_coherent_gain = (double)d_nb2_fsize / sum;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_fsize; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_window[i] *= inv_coherent_gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.msize = d_nb2_msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.mask = d_nb2_mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.lambda_y = (double *)malloc(d_nb2_msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.lambda_d = (double *)malloc(d_nb2_msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.prev_gamma = (double *)malloc(d_nb2_msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.prev_mask = (double *)malloc(d_nb2_msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.gf1p5 = sqrt(3.1415926) / 2.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.98);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.alpha = exp(-d_nb2_incr / d_nb2_rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.eps_floor = 1.0e-300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.gamma_max = 1000.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.q = 0.2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_g.msize; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.prev_mask[i] = 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.prev_gamma[i] = 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.gmax = 10000.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.incr = d_nb2_incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.rate = d_nb2_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.msize = d_nb2_msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.lambda_y = d_nb2_g.lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.lambda_d = d_nb2_g.lambda_d;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.7);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaCsmooth = exp(-d_nb2_np.incr / d_nb2_np.rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.96);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaMax = exp(-d_nb2_np.incr / d_nb2_np.rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.7);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaCmin = exp(-d_nb2_np.incr / d_nb2_np.rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.3);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaMin_max_value = exp(-d_nb2_np.incr / d_nb2_np.rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.snrq = -d_nb2_np.incr / (0.064 * d_nb2_np.rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.betamax = exp(-d_nb2_np.incr / d_nb2_np.rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.invQeqMax = 0.5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.av = 2.12;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.Dtime = 8.0 * 12.0 * 128.0 / 8000.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.U = 8;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.V = (int)(0.5 + (d_nb2_np.Dtime * d_nb2_np.rate / (d_nb2_np.U * d_nb2_np.incr)));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_np.V < 4) d_nb2_np.V = 4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ((d_nb2_np.U = (int)(0.5 + (d_nb2_np.Dtime * d_nb2_np.rate / (d_nb2_np.V * d_nb2_np.incr)))) < 1) d_nb2_np.U = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.D = d_nb2_np.U * d_nb2_np.V;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ interpM(&d_nb2_np.MofD, d_nb2_np.D, 18, Dvals, Mvals);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ interpM(&d_nb2_np.MofV, d_nb2_np.V, 18, Dvals, Mvals);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.invQbar_points[0] = 0.03;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.invQbar_points[1] = 0.05;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.invQbar_points[2] = 0.06;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.invQbar_points[3] = 1.0e300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double db;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ db = 10.0 * log10(8.0) / (12.0 * 128 / 8000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.nsmax[0] = pow(10.0, db / 10.0 * d_nb2_np.V * d_nb2_np.incr / d_nb2_np.rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ db = 10.0 * log10(4.0) / (12.0 * 128 / 8000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.nsmax[1] = pow(10.0, db / 10.0 * d_nb2_np.V * d_nb2_np.incr / d_nb2_np.rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ db = 10.0 * log10(2.0) / (12.0 * 128 / 8000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.nsmax[2] = pow(10.0, db / 10.0 * d_nb2_np.V * d_nb2_np.incr / d_nb2_np.rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ db = 10.0 * log10(1.2) / (12.0 * 128 / 8000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.nsmax[3] = pow(10.0, db / 10.0 * d_nb2_np.V * d_nb2_np.incr / d_nb2_np.rate);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.p = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaOptHat = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaHat = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.sigma2N = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.pbar = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.p2bar = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.Qeq = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.bmin = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.bmin_sub = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.k_mod = (int *)malloc(d_nb2_np.msize * sizeof(int));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin_sub = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.lmin_flag = (int *)malloc(d_nb2_np.msize * sizeof(int));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.pmin_u = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actminbuff = (double**)malloc(d_nb2_np.U * sizeof(double*));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_np.U; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actminbuff[i] = (double *)malloc(d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int k, ku;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaC = 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.subwc = d_nb2_np.V;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.amb_idx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++) d_nb2_np.lambda_y[k] = 0.5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy(d_nb2_np.p, d_nb2_np.lambda_y, d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy(d_nb2_np.sigma2N, d_nb2_np.lambda_y, d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy(d_nb2_np.pbar, d_nb2_np.lambda_y, d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy(d_nb2_np.pmin_u, d_nb2_np.lambda_y, d_nb2_np.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.p2bar[k] = d_nb2_np.lambda_y[k] * d_nb2_np.lambda_y[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin[k] = 1.0e300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin_sub[k] = 1.0e300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (ku = 0; ku < d_nb2_np.U; ku++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actminbuff[ku][k] = 1.0e300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset(d_nb2_np.lmin_flag, 0, d_nb2_np.msize * sizeof(int));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.incr = d_nb2_incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.rate = d_nb2_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.msize = d_nb2_msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.lambda_y = d_nb2_g.lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.lambda_d = d_nb2_g.lambda_d;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.8);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.alpha_pow = exp(-d_nb2_nps.incr / d_nb2_nps.rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double tau = -128.0 / 8000.0 / log(0.9);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.alpha_Pbar = exp(-d_nb2_nps.incr / d_nb2_nps.rate / tau);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.epsH1 = pow(10.0, 15.0 / 10.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.epsH1r = d_nb2_nps.epsH1 / (1.0 + d_nb2_nps.epsH1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.sigma2N = (double *)malloc(d_nb2_nps.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.PH1y = (double *)malloc(d_nb2_nps.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.Pbar = (double *)malloc(d_nb2_nps.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.EN2y = (double *)malloc(d_nb2_nps.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_nps.msize; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.sigma2N[i] = 0.5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nps.Pbar[i] = 0.5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.msize = d_nb2_msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.lambda_y = d_nb2_g.lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.zetaThresh = 0.75;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.psi = 10.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.nmask = (double *)malloc(d_nb2_ae.msize * sizeof(double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb2_inaccum, 0, d_nb2_iasize * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_ovrlp; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb2_save[i], 0, d_nb2_fsize * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb2_outaccum, 0, d_nb2_oasize * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nsamps = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iainidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iaoutidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oainidx = d_nb2_init_oainidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oaoutidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_saveidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx_nb_cc::~rx_nb_cc()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ delete d_nb2_fft1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ delete d_nb2_fft2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_ae.nmask);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_nps.EN2y);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_nps.Pbar);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_nps.PH1y);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_nps.sigma2N);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_np.U; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.actminbuff[i]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.actminbuff);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.pmin_u);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.lmin_flag);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.actmin_sub);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.actmin);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.k_mod);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.bmin_sub);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.bmin);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.Qeq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.p2bar);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.pbar);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.sigma2N);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.alphaHat);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.alphaOptHat);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_np.p);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_g.prev_mask);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_g.prev_gamma);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_g.lambda_d);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_g.lambda_y);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_outaccum);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_ovrlp; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_save[i]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_save);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_mask);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_inaccum);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ free(d_nb2_window);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -68,30 +359,38 @@ int rx_nb_cc::work(int noutput_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr_vector_const_void_star &input_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr_vector_void_star &output_items)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- const gr_complex *in = (const gr_complex *) input_items[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- gr_complex *out = (gr_complex *) output_items[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const float *in = (const float *) input_items[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ float *out = (float *) output_items[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ boost::mutex::scoped_lock lock(d_mutex);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // copy data into output buffer then perform the processing on that buffer
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for (i = 0; i < noutput_items; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (noutput_items < d_nb2_bsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- out[i] = in[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_bsize; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ out[i] = in[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (d_nb1_on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- process_nb1(out, noutput_items);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (d_nb2_on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- process_nb2(out, noutput_items);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ process_nb2(out, d_nb2_bsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb1_on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ process_nb1(out, d_nb2_bsize);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return d_nb2_bsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return noutput_items;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*! \brief Perform noise blanker 1 processing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * \param buf The data buffer holding gr_complex samples.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * \param num The number of samples in the buffer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -101,35 +400,156 @@ int rx_nb_cc::work(int noutput_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * FIXME: Needs different constants for higher sample rates?
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-void rx_nb_cc::process_nb1(gr_complex *buf, int num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void rx_nb_cc::process_nb1(float *buf, int num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- float cmag;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- gr_complex zero(0.0, 0.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for (int i = 0; i < num; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int i, j, idx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double c0, c1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double y, error, sigma, inv_sigp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double nel, nev;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < num; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cmag = abs(buf[i]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_delay[d_sigidx] = buf[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_avgmag_nb1 = 0.999*d_avgmag_nb1 + 0.001*cmag;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_d[d_nb1_in_idx] = buf[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ y = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sigma = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (j = 0; j < d_nb1_n_taps; j++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ idx = (d_nb1_in_idx + j + d_nb1_delay) & d_nb1_mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ y += d_nb1_w[j] * d_nb1_d[idx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sigma += d_nb1_d[idx] * d_nb1_d[idx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ inv_sigp = 1.0 / (sigma + 1e-10);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ error = d_nb1_d[d_nb1_in_idx] - y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ buf[i] = (float)(y * 1.5f); // gain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if((nel = error * (1.0 - d_nb1_two_mu * sigma * inv_sigp)) < 0.0) nel = -nel;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if((nev = d_nb1_d[d_nb1_in_idx] - (1.0 - d_nb1_two_mu * d_nb1_ngamma) * y - d_nb1_two_mu * error * sigma * inv_sigp) < 0.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ nev = -nev;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (nev < nel)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if((d_nb1_lidx += d_nb1_lincr) > d_nb1_lidx_max) d_nb1_lidx = d_nb1_lidx_max;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if((d_nb1_lidx -= d_nb1_ldecr) < d_nb1_lidx_min) d_nb1_lidx = d_nb1_lidx_min;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_ngamma = d_nb1_gamma * (d_nb1_lidx * d_nb1_lidx) * (d_nb1_lidx * d_nb1_lidx) * d_nb1_den_mult;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if ((d_hangtime == 0) && (cmag > (d_thld_nb1*d_avgmag_nb1)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_hangtime = 7;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ c0 = 1.0 - d_nb1_two_mu * d_nb1_ngamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ c1 = d_nb1_two_mu * error * inv_sigp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (d_hangtime > 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (j = 0; j < d_nb1_n_taps; j++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- buf[i] = zero;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_hangtime--;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ idx = (d_nb1_in_idx + j + d_nb1_delay) & d_nb1_mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_w[j] = c0 * d_nb1_w[j] + c1 * d_nb1_d[idx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_in_idx = (d_nb1_in_idx + d_nb1_mask) & d_nb1_mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// Helper functions
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double bessI0 (double x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double res, p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (x == 0.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ res = 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (x < 0.0) x = -x;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (x <= 3.75)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ p = x / 3.75;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ p = p * p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ res = ((((( 0.0045813 * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.0360768) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.2659732) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 1.2067492) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 3.0899424) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 3.5156229) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- buf[i] = d_delay[d_delidx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ p = 3.75 / x;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ res = exp (x) / sqrt (x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * (((((((( + 0.00392377 * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ - 0.01647633) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.02635537) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ - 0.02057706) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.00916281) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ - 0.00157565) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.00225319) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.01328592) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.39894228);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return res;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_sigidx = (d_sigidx + 7) & 7;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_delidx = (d_delidx + 7) & 7;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++double bessI1 (double x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double res, p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (x == 0.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ res = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (x < 0.0) x = -x;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (x <= 3.75)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ p = x / 3.75;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ p = p * p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ res = x
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * (((((( 0.00032411 * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.00301532) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.02658733) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.15084934) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.51498869) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.87890594) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.5);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ p = 3.75 / x;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ res = exp (x) / sqrt (x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * (((((((( - 0.00420059 * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.01787654) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ - 0.02895312) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.02282967) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ - 0.01031555) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.00163801) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ - 0.00362018) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ - 0.03988024) * p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + 0.39894228);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return res;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void rx_nb_cc::interpM (double* res, double x, int nvals, double* xvals, double* yvals)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (x <= xvals[0])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *res = yvals[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else if (x >= xvals[nvals - 1])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *res = yvals[nvals - 1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int idx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double xllow, xlhigh, frac;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while (x >= xvals[idx]) idx++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ xllow = log10 (xvals[idx - 1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ xlhigh = log10(xvals[idx]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ frac = (log10 (x) - xllow) / (xlhigh - xllow);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *res = yvals[idx - 1] + frac * (yvals[idx] - yvals[idx - 1]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*! \brief Perform noise blanker 2 processing.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * \param buf The data buffer holding gr_complex samples.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * \param num The number of samples in the buffer.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -139,21 +559,246 @@ void rx_nb_cc::process_nb1(gr_complex *buf, int num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * FIXME: Needs different constants for higher sample rates?
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-void rx_nb_cc::process_nb2(gr_complex *buf, int num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void rx_nb_cc::process_nb2(float *buf, int num)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- float cmag;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- gr_complex c1(0.75);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- gr_complex c2(0.25);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int i, j, k, sbuff, sbegin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double g1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double f0, f1, f2, f3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double sum_prev_p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double sum_lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alphaCtilda;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double sum_prev_sigma2N;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alphaMin, SNR;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double beta, varHat, invQeq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double invQbar;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double bc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double QeqTilda, QeqTildaSub;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double noise_slope_max;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int m;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int N, n;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double sumPre, sumPost, zeta, zetaT;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < num; i ++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_inaccum[d_nb2_iainidx] = (double)buf[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iainidx = (d_nb2_iainidx + 1) % d_nb2_iasize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nsamps += num;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while (d_nb2_nsamps >= d_nb2_fsize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ float *in1 = d_nb2_fft1->get_inbuf();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0, j = d_nb2_iaoutidx; i < d_nb2_fsize; i++, j = (j + 1) % d_nb2_iasize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ in1[i] = (float)d_nb2_window[i] * (float)d_nb2_inaccum[j];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iaoutidx = (d_nb2_iaoutidx + d_nb2_incr) % d_nb2_iasize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nsamps -= d_nb2_incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_fft1->execute();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // calc_gain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr_complex *out1 = d_nb2_fft1->get_outbuf();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_g.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.lambda_y[k] = out1[k].real()*out1[k].real();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.lambda_y[k] += out1[k].imag()*out1[k].imag();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // LambdaD
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum_prev_p = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum_lambda_y = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum_prev_sigma2N = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum_prev_p += d_nb2_np.p[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum_lambda_y += d_nb2_np.lambda_y[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sum_prev_sigma2N += d_nb2_np.sigma2N[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ f0 = d_nb2_np.p[k] / d_nb2_np.sigma2N[k] - 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaOptHat[k] = 1.0 / (1.0 + f0 * f0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SNR = sum_prev_p / sum_prev_sigma2N;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ alphaMin = std::min(d_nb2_np.alphaMin_max_value, pow (SNR, d_nb2_np.snrq));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_np.alphaOptHat[k] < alphaMin) d_nb2_np.alphaOptHat[k] = alphaMin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ f1 = sum_prev_p / sum_lambda_y - 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ alphaCtilda = 1.0 / (1.0 + f1 * f1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaC = d_nb2_np.alphaCsmooth * d_nb2_np.alphaC + (1.0 - d_nb2_np.alphaCsmooth) * std::max (alphaCtilda, d_nb2_np.alphaCmin);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ f2 = d_nb2_np.alphaMax * d_nb2_np.alphaC;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.alphaHat[k] = f2 * d_nb2_np.alphaOptHat[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.p[k] = d_nb2_np.alphaHat[k] * d_nb2_np.p[k] + (1.0 - d_nb2_np.alphaHat[k]) * d_nb2_np.lambda_y[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ invQbar = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ beta = std::min (d_nb2_np.betamax, d_nb2_np.alphaHat[k] * d_nb2_np.alphaHat[k]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.pbar[k] = beta * d_nb2_np.pbar[k] + (1.0 - beta) * d_nb2_np.p[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.p2bar[k] = beta * d_nb2_np.p2bar[k] + (1.0 - beta) * d_nb2_np.p[k] * d_nb2_np.p[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ varHat = d_nb2_np.p2bar[k] - d_nb2_np.pbar[k] * d_nb2_np.pbar[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ invQeq = varHat / (2.0 * d_nb2_np.sigma2N[k] * d_nb2_np.sigma2N[k]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (invQeq > d_nb2_np.invQeqMax) invQeq = d_nb2_np.invQeqMax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.Qeq[k] = 1.0 / invQeq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ invQbar += invQeq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ invQbar /= (double)d_nb2_np.msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bc = 1.0 + d_nb2_np.av * sqrt (invQbar);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QeqTilda = (d_nb2_np.Qeq[k] - 2.0 * d_nb2_np.MofD) / (1.0 - d_nb2_np.MofD);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QeqTildaSub = (d_nb2_np.Qeq[k] - 2.0 * d_nb2_np.MofV) / (1.0 - d_nb2_np.MofV);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.bmin[k] = 1.0 + 2.0 * (d_nb2_np.D - 1.0) / QeqTilda;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.bmin_sub[k] = 1.0 + 2.0 * (d_nb2_np.V - 1.0) / QeqTildaSub;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb2_np.k_mod, 0, d_nb2_np.msize * sizeof (int));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ f3 = d_nb2_np.p[k] * d_nb2_np.bmin[k] * bc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (f3 < d_nb2_np.actmin[k])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin[k] = f3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin_sub[k] = d_nb2_np.p[k] * d_nb2_np.bmin_sub[k] * bc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.k_mod[k] = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_np.subwc == d_nb2_np.V)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (invQbar < d_nb2_np.invQbar_points[0]) noise_slope_max = d_nb2_np.nsmax[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else if (invQbar < d_nb2_np.invQbar_points[1]) noise_slope_max = d_nb2_np.nsmax[1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else if (invQbar < d_nb2_np.invQbar_points[2]) noise_slope_max = d_nb2_np.nsmax[2];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else noise_slope_max = d_nb2_np.nsmax[3];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int ku;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double min;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_np.k_mod[k])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.lmin_flag[k] = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actminbuff[d_nb2_np.amb_idx][k] = d_nb2_np.actmin[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ min = 1.0e300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (ku = 0; ku < d_nb2_np.U; ku++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_np.actminbuff[ku][k] < min) min = d_nb2_np.actminbuff[ku][k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.pmin_u[k] = min;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ((d_nb2_np.lmin_flag[k] == 1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ && (d_nb2_np.actmin_sub[k] < noise_slope_max * d_nb2_np.pmin_u[k])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ && (d_nb2_np.actmin_sub[k] > d_nb2_np.pmin_u[k]))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.pmin_u[k] = d_nb2_np.actmin_sub[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (ku = 0; ku < d_nb2_np.U; ku++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actminbuff[ku][k] = d_nb2_np.actmin_sub[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.lmin_flag[k] = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin[k] = 1.0e300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.actmin_sub[k] = 1.0e300;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (++d_nb2_np.amb_idx == d_nb2_np.U) d_nb2_np.amb_idx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.subwc = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_np.subwc > 1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_np.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_np.k_mod[k])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.lmin_flag[k] = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.sigma2N[k] = std::min (d_nb2_np.actmin_sub[k], d_nb2_np.pmin_u[k]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_np.pmin_u[k] = d_nb2_np.sigma2N[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ++d_nb2_np.subwc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy (d_nb2_np.lambda_d, d_nb2_np.sigma2N, d_nb2_np.msize * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // gain mode 0 (not 2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double gamma, eps_hat, v;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gamma = std::min (d_nb2_g.lambda_y[k] / d_nb2_g.lambda_d[k], d_nb2_g.gamma_max);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ eps_hat = d_nb2_g.alpha * d_nb2_g.prev_mask[k] * d_nb2_g.prev_mask[k] * d_nb2_g.prev_gamma[k]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ + (1.0 - d_nb2_g.alpha) * std::max (gamma - 1.0, d_nb2_g.eps_floor);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ v = (eps_hat / (1.0 + eps_hat)) * gamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.mask[k] = d_nb2_g.gf1p5 * sqrt (v) / gamma * exp (- 0.5 * v)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * ((1.0 + v) * bessI0 (0.5 * v) + v * bessI1 (0.5 * v));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double v2 = std::min (v, 700.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double eta = d_nb2_g.mask[k] * d_nb2_g.mask[k] * d_nb2_g.lambda_y[k] / d_nb2_g.lambda_d[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double eps = eta / (1.0 - d_nb2_g.q);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double witchHat = (1.0 - d_nb2_g.q) / d_nb2_g.q * exp (v2) / (1.0 + eps);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.mask[k] *= witchHat / (1.0 + witchHat);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_g.mask[k] > d_nb2_g.gmax) d_nb2_g.mask[k] = d_nb2_g.gmax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (d_nb2_g.mask[k] != d_nb2_g.mask[k]) d_nb2_g.mask[k] = 0.01;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.prev_gamma[k] = gamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_g.prev_mask[k] = d_nb2_g.mask[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sumPre = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sumPost = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = 0; k < d_nb2_ae.msize; k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sumPre += d_nb2_ae.lambda_y[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sumPost += d_nb2_mask[k] * d_nb2_mask[k] * d_nb2_ae.lambda_y[k];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ zeta = sumPost / sumPre;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (zeta >= d_nb2_ae.zetaThresh)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ zetaT = 1.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ zetaT = zeta;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (zetaT == 1.0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ N = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ N = 1 + 2 * (int)(0.5 + d_nb2_ae.psi * (1.0 - zetaT / d_nb2_ae.zetaThresh));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ n = N / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (k = n; k < (d_nb2_ae.msize - n); k++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.nmask[k] = 0.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (m = k - n; m <= (k + n); m++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.nmask[k] += d_nb2_mask[m];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_ae.nmask[k] /= (double)N;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memcpy (d_nb2_mask + n, d_nb2_ae.nmask, (d_nb2_ae.msize - 2 * n) * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // end calc_gain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr_complex *in2 = d_nb2_fft2->get_inbuf();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_msize; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ g1 = d_nb2_gain * d_nb2_mask[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ in2[i] = gr_complex(g1 * out1[i].real(),g1 * out1[i].imag());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_fft2->execute();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ float *out2 = d_nb2_fft2->get_outbuf();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < d_nb2_fsize; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_save[d_nb2_saveidx][i] = d_nb2_window[i] * out2[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = d_nb2_ovrlp; i > 0; i--)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sbuff = (d_nb2_saveidx + i) % d_nb2_ovrlp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ sbegin = d_nb2_incr * (d_nb2_ovrlp - i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (j = sbegin, k = d_nb2_oainidx; j < d_nb2_incr + sbegin; j++, k = (k + 1) % d_nb2_oasize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ( i == d_nb2_ovrlp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_outaccum[k] = d_nb2_save[sbuff][j];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_outaccum[k] += d_nb2_save[sbuff][j];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_saveidx = (d_nb2_saveidx + 1) % d_nb2_ovrlp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oainidx = (d_nb2_oainidx + d_nb2_incr) % d_nb2_oasize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (i = 0; i < num; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ buf[i] = (float)d_nb2_outaccum[d_nb2_oaoutidx] * 1.5f;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oaoutidx = (d_nb2_oaoutidx + 1) % d_nb2_oasize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for (int i = 0; i < num; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- cmag = abs(buf[i]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_avgsig = c1*d_avgsig + c2*buf[i];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- d_avgmag_nb2 = 0.999*d_avgmag_nb2 + 0.001*cmag;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (cmag > d_thld_nb2*d_avgmag_nb2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- buf[i] = d_avgsig;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void rx_nb_cc::set_threshold1(float threshold)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/dsp/rx_noise_blanker_cc.h src/dsp/rx_noise_blanker_cc.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 8b4907e..a99924b 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/dsp/rx_noise_blanker_cc.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/dsp/rx_noise_blanker_cc.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -25,6 +25,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/sync_block.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <gnuradio/gr_complex.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/fft/fft.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <boost/thread/mutex.hpp>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ class rx_nb_cc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -60,22 +61,46 @@ protected:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ~rx_nb_cc();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void forecast (int noutput_items, gr_vector_int &ninput_items_required);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int work(int noutput_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr_vector_const_void_star &input_items,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr_vector_void_star &output_items);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void set_sample_rate(double sample_rate) { d_sample_rate = sample_rate; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- void set_nb1_on(bool nb1_on) { d_nb1_on = nb1_on; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- void set_nb2_on(bool nb2_on) { d_nb2_on = nb2_on; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void set_nb1_on(bool nb1_on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb1_d, 0, sizeof(double) * 2048);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb1_w, 0, sizeof(double) * 2048);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_in_idx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb1_on = nb1_on;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void set_nb2_on(bool nb2_on)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb2_inaccum, 0, d_nb2_iasize * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < d_nb2_ovrlp; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb2_save[i], 0, d_nb2_fsize * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ memset (d_nb2_outaccum, 0, d_nb2_oasize * sizeof (double));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_nsamps = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iainidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_iaoutidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oainidx = d_nb2_init_oainidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_oaoutidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_saveidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ d_nb2_on = nb2_on;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool get_nb1_on() { return d_nb1_on; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool get_nb2_on() { return d_nb2_on; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void set_threshold1(float threshold);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void set_threshold2(float threshold);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- void process_nb1(gr_complex *buf, int num);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- void process_nb2(gr_complex *buf, int num);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void process_nb1(float *buf, int num);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void process_nb2(float *buf, int num);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void interpM (double* res, double x, int nvals, double* xvals, double* yvals);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ boost::mutex d_mutex; /*! Used to lock internal data while processing or setting parameters. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -89,8 +114,145 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ float d_avgmag_nb2; /*! Average magnitude. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr_complex d_avgsig, d_delay[8];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int d_delidx, d_sigidx, d_hangtime; // FIXME: need longer buffer for higher sampel rates?
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb1_state;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_state;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // NB1 parameters
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb1_dline_size;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb1_mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb1_n_taps;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb1_delay;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_two_mu;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double ed_nb1_gamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb1_in_idx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_lidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_lidx_min;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_lidx_max;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_ngamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_gamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_den_mult;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_lincr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_ldecr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_d[2048];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb1_w[2048];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // NB2 parameters
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_fsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_bsize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_ovrlp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* d_nb2_window;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_iasize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* d_nb2_inaccum;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* d_nb2_forfftin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr_complex* d_nb2_forfftout;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* d_nb2_mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr_complex* d_nb2_revfftin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* d_nb2_revfftout;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double** d_nb2_save;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_oasize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* d_nb2_outaccum;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb2_rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb2_ogain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double d_nb2_gain;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_nsamps;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_iainidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_iaoutidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_init_oainidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_oainidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_oaoutidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int d_nb2_saveidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ struct _g
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* lambda_d;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* prev_mask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* prev_gamma;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double gf1p5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alpha;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double eps_floor;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double gamma_max;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double q;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double gmax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } d_nb2_g;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ struct _npest
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* lambda_d;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* p;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* alphaOptHat;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alphaC;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alphaCsmooth;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alphaCmin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* alphaHat;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alphaMax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* sigma2N;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alphaMin_max_value;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double snrq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double betamax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* pbar;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* p2bar;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double invQeqMax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double av;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* Qeq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int U;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double Dtime;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int V;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int D;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double MofD;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double MofV;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* bmin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* bmin_sub;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int* k_mod;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* actmin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* actmin_sub;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int subwc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int* lmin_flag;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* pmin_u;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double invQbar_points[4];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double nsmax[4];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double** actminbuff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int amb_idx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } d_nb2_np;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ struct _npests
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int incr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double rate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* lambda_d;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alpha_pow;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double alpha_Pbar;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double epsH1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double epsH1r;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* sigma2N;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* PH1y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* Pbar;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* EN2y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } d_nb2_nps;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ struct _ae
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int msize;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* lambda_y;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double zetaThresh;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double psi;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ double* nmask;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } d_nb2_ae;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::fft::fft_real_fwd *d_nb2_fft1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ gr::fft::fft_real_rev *d_nb2_fft2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif /* RX_NB_CC_H */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/CMakeLists.txt src/qtgui/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 38db002..677858f 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/CMakeLists.txt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -7,6 +7,8 @@ add_source_files(SRCS_LIST
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ agc_options.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ audio_options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ audio_options.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bandplan.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bandplan.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bookmarks.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bookmarks.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bookmarkstablemodel.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -44,6 +46,8 @@ add_source_files(SRCS_LIST
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ plotter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ qtcolorpicker.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ qtcolorpicker.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_spots.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #######################################################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -62,5 +66,6 @@ add_source_files(UI_SRCS_LIST
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ioconfig.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ iq_tool.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ nb_options.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxc_options.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/bandplan.cpp src/qtgui/bandplan.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..25a9d96
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/bandplan.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,112 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * http://gqrx.dk/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with Gqrx; see the file COPYING. If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <Qt>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QFile>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QStringList>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QTextStream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QString>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QSet>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <algorithm>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "bandplan.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <wchar.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++BandPlan* BandPlan::m_pThis = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++BandPlan::BandPlan()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void BandPlan::create()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_pThis = new BandPlan;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++BandPlan& BandPlan::Get()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return *m_pThis;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void BandPlan::setConfigDir(const QString& cfg_dir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_bandPlanFile = cfg_dir + "/bandplan.csv";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ printf("BandPlanFile is %s\n", m_bandPlanFile.toStdString().c_str());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++bool BandPlan::load()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QFile file(m_bandPlanFile);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_BandInfoList.clear();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while (!file.atEnd())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString line = QString::fromUtf8(file.readLine().trimmed());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(line.isEmpty() || line.startsWith("#"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QStringList strings = line.split(",");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (strings.count() < 6){
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ printf("BandPlan: Ignoring Line:\n %s\n", line.toLatin1().data());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BandInfo info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.minFrequency = strings[0].toLongLong();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.maxFrequency = strings[1].toLongLong();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.modulation = strings[2].trimmed();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.step = strings[3].toInt();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.color = QColor(strings[4].trimmed());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.name = strings[5].trimmed();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_BandInfoList.append(info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ file.close();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ emit BandPlanChanged();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++QList<BandInfo> BandPlan::getBandsInRange(qint64 low, qint64 high)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BandInfo> found;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < m_BandInfoList.size(); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(m_BandInfoList[i].maxFrequency < low) continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(m_BandInfoList[i].minFrequency > high) continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ found.append(m_BandInfoList[i]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return found;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++QList<BandInfo> BandPlan::getBandsEncompassing(qint64 freq)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BandInfo> found;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < m_BandInfoList.size(); i++) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(m_BandInfoList[i].maxFrequency < freq) continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(m_BandInfoList[i].minFrequency > freq) continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ found.append(m_BandInfoList[i]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return found;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+\ No newline at end of file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/bandplan.h src/qtgui/bandplan.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..115dcda
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/bandplan.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,83 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * http://gqrx.dk/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with Gqrx; see the file COPYING. If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef BANDPLAN_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define BANDPLAN_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QtGlobal>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QObject>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QString>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QMap>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QList>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QStringList>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QColor>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct BandInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ qint64 minFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ qint64 maxFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString modulation;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ qint64 step;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QColor color;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BandInfo()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ this->minFrequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ this->maxFrequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ this->step = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool operator<(const BandInfo &other) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return minFrequency < other.minFrequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class BandPlan : public QObject
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Q_OBJECT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // This is a Singleton Class now because you can not send qt-signals from static functions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static void create();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static BandPlan& Get();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool load();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int size() { return m_BandInfoList.size(); }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BandInfo& getBand(int i) { return m_BandInfoList[i]; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BandInfo> getBandsInRange(qint64 low, qint64 high);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BandInfo> getBandsEncompassing(qint64 freq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void setConfigDir(const QString&);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BandPlan(); // Singleton Constructor is private.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BandInfo> m_BandInfoList;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString m_bandPlanFile;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static BandPlan* m_pThis;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++signals:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void BandPlanChanged(void);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif // BANDPLAN_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dockaudio.cpp src/qtgui/dockaudio.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index ff920ec..c20b07e 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/dockaudio.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dockaudio.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -74,6 +74,7 @@ DockAudio::DockAudio(QWidget *parent) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->audioSpectrum->setFilterBoxEnabled(false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->audioSpectrum->setCenterLineEnabled(false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->audioSpectrum->setBookmarksEnabled(false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->audioSpectrum->setBandPlanEnabled(false);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->audioSpectrum->setFftRange(-80., 0.);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->audioSpectrum->setVdivDelta(40);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->audioSpectrum->setHdivDelta(40);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dockfft.cpp src/qtgui/dockfft.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index e91cfa1..3ec577f 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/dockfft.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dockfft.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -274,6 +274,12 @@ void DockFft::saveSettings(QSettings *settings)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ settings->remove("db_ranges_locked");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Band Plan
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (ui->bandPlanCheckbox->isChecked())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->setValue("bandplan", true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->remove("bandplan");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (QString::compare(ui->cmapComboBox->currentData().toString(), DEFAULT_COLORMAP))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ settings->setValue("waterfall_colormap", ui->cmapComboBox->currentData().toString());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -346,6 +352,10 @@ void DockFft::readSettings(QSettings *settings)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool_val = settings->value("db_ranges_locked", false).toBool();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->lockButton->setChecked(bool_val);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool_val = settings->value("bandplan", false).toBool();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->bandPlanCheckbox->setChecked(bool_val);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ emit bandPlanChanged(bool_val);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QString cmap = settings->value("waterfall_colormap", "gqrx").toString();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ui->cmapComboBox->setCurrentIndex(ui->cmapComboBox->findData(cmap));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -522,6 +532,11 @@ void DockFft::on_peakDetectionButton_toggled(bool checked)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ emit peakDetectionToggled(checked);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DockFft::on_bandPlanCheckbox_stateChanged(int state)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ emit bandPlanChanged(state == 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /** lock button toggled */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void DockFft::on_lockButton_toggled(bool checked)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dockfft.h src/qtgui/dockfft.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 5d8fb7f..b888cd1 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/dockfft.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dockfft.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -67,6 +67,7 @@ signals:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void fftFillToggled(bool fill); /*! Toggle filling area under FFT plot. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void fftPeakHoldToggled(bool enable); /*! Toggle peak hold in FFT area. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void peakDetectionToggled(bool enabled); /*! Enable peak detection in FFT plot */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void bandPlanChanged(bool enabled); /*! Toggle Band Plan at bottom of FFT area. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void wfColormapChanged(const QString &cmap);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ public slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -93,6 +94,7 @@ private slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_peakHoldButton_toggled(bool checked);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_peakDetectionButton_toggled(bool checked);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_lockButton_toggled(bool checked);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void on_bandPlanCheckbox_stateChanged(int state);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void on_cmapComboBox_currentIndexChanged(int index);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dockfft.ui src/qtgui/dockfft.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 033cc19..749eaaf 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/dockfft.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dockfft.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -851,7 +851,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- <item row="14" column="0" colspan="4">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="15" column="0" colspan="4">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <spacer name="verticalSpacer">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <property name="orientation">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <enum>Qt::Vertical</enum>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -939,8 +939,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </size>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <property name="toolTip">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- <string><html>Number of FFT points to calculate. Higher values will require more CPU time. This will not influence the number of points on the display since that parameter is adjusted automatically according to the display size.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-</html></string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string><html>Number of FFT points to calculate. Higher values will require more CPU time. This will not influence the number of points on the display since that parameter is adjusted automatically according to the display size.</html></string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <property name="editable">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ <bool>false</bool>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1107,6 +1106,16 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="14" column="0" colspan="4">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QCheckBox" name="bandPlanCheckbox">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="toolTip">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Enable Band Plan on bottom of spectrum</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Enable Band Plan</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </layout>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ </layout>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dxc_options.cpp src/qtgui/dxc_options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..d30e2ca
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dxc_options.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,119 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dxc_options.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "ui_dxc_options.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QTcpSocket>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QString>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QStringList>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dxc_spots.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DXC_Options::DXC_Options(QWidget *parent) :
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QDialog(parent),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui(new Ui::DXC_Options)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->setupUi(this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TCPSocket = new QTcpSocket(this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(TCPSocket, SIGNAL(connected()),this, SLOT(connected()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(TCPSocket, SIGNAL(disconnected()),this, SLOT(disconnected()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(TCPSocket, SIGNAL(readyRead()),this, SLOT(readyToRead()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DXC_Options::~DXC_Options()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ delete ui;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*! \brief Catch window close events.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * This method is called when the user closes the audio options dialog
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * window using the window close icon. We catch the event and hide the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * dialog but keep it around for later use.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::closeEvent(QCloseEvent *event)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ hide();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ event->ignore();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*! \brief Catch window show events. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::showEvent(QShowEvent * event)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Q_UNUSED(event);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::on_pushButton_DXCConnect_clicked()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpots::Get().setSpotTimeout(ui->lineEdit_DXCSpottimeout->text().toInt());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TCPSocket->connectToHost(ui->lineEdit_DXCAddress->text(),ui->lineEdit_DXCPort->text().toInt());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(!TCPSocket->waitForConnected(5000))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->plainTextEdit_DXCMonitor->appendPlainText(TCPSocket->errorString());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::on_pushButton_DXCDisconnect_clicked()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TCPSocket->close();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::connected()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->plainTextEdit_DXCMonitor->appendPlainText("Connected");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->pushButton_DXCConnect->setDisabled(true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->pushButton_DXCDisconnect->setEnabled(true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::disconnected()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->plainTextEdit_DXCMonitor->appendPlainText("Disconnected");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->pushButton_DXCDisconnect->setDisabled(true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->pushButton_DXCConnect->setEnabled(true);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::readyToRead()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpotInfo info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QStringList Spot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString incommingMessage;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ incommingMessage = TCPSocket->readAll();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->plainTextEdit_DXCMonitor->appendPlainText(incommingMessage);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(incommingMessage.contains("enter your call", Qt::CaseInsensitive))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TCPSocket->write(ui->lineEdit_DXCUSername->text().append("\r\n").toUtf8());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->plainTextEdit_DXCMonitor->appendPlainText(ui->lineEdit_DXCUSername->text().append("\r\n"));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else if(incommingMessage.contains("DX de", Qt::CaseInsensitive) &&
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ incommingMessage.contains(ui->lineEdit_DXCFilter->text()))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Spot = incommingMessage.split(" ", QString::SkipEmptyParts);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.name = Spot[4].trimmed();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.frequency = Spot[3].toDouble() * 1000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpots::Get().add(info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::saveSettings(QSettings *settings)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!settings)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->beginGroup("dxcluster");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->setValue("DXCAddress", ui->lineEdit_DXCAddress->text());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->setValue("DXCPort", ui->lineEdit_DXCPort->text());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->setValue("DXCUsername", ui->lineEdit_DXCUSername->text());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->setValue("DXCSpotTimeout", ui->lineEdit_DXCSpottimeout->text());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->setValue("DXCFilter", ui->lineEdit_DXCFilter->text());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->endGroup();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXC_Options::readSettings(QSettings *settings)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (!settings)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->beginGroup("dxcluster");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->lineEdit_DXCAddress->setText(settings->value("DXCAddress", "localhost").toString());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->lineEdit_DXCPort->setText(settings->value("DXCPort", "7300").toString());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->lineEdit_DXCUSername->setText(settings->value("DXCUsername", "nocall").toString());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->lineEdit_DXCSpottimeout->setText(settings->value("DXCSpotTimeout", "10").toString());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ui->lineEdit_DXCFilter->setText(settings->value("DXCFilter", "").toString());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ settings->endGroup();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dxc_options.h src/qtgui/dxc_options.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..b026c02
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dxc_options.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,42 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef DXC_OPTIONS_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define DXC_OPTIONS_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QCloseEvent>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QShowEvent>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QTcpSocket>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QSettings>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QDialog>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++namespace Ui {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class DXC_Options;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class DXC_Options : public QDialog
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Q_OBJECT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ explicit DXC_Options(QWidget *parent = 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ ~DXC_Options();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void closeEvent(QCloseEvent *event);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void showEvent(QShowEvent * event);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void saveSettings(QSettings *settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void readSettings(QSettings *settings);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void on_pushButton_DXCConnect_clicked();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void on_pushButton_DXCDisconnect_clicked();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void connected();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void disconnected();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void readyToRead();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Ui::DXC_Options *ui;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QTcpSocket *TCPSocket;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif // DXC_OPTIONS_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dxc_options.ui src/qtgui/dxc_options.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..c0d7387
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dxc_options.ui
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,168 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<?xml version="1.0" encoding="UTF-8"?>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++<ui version="4.0">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <class>DXC_Options</class>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QDialog" name="DXC_Options">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="geometry">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <rect>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <x>0</x>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <y>0</y>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <width>500</width>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <height>405</height>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </rect>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="windowTitle">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>DXC Options</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <layout class="QGridLayout" name="gridLayout_2">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="0" column="0">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QGroupBox" name="groupBox">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="title">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>DX Cluster Settings</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <layout class="QGridLayout" name="gridLayout">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="1" column="0" colspan="2">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLabel" name="label_DXCSpottimeout">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="sizePolicy">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <horstretch>0</horstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <verstretch>0</verstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </sizepolicy>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Spot Timeout/min:</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="2" column="0" colspan="2">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLabel" name="label_DXCUsername">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="sizePolicy">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <horstretch>0</horstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <verstretch>0</verstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </sizepolicy>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Username:</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="0" column="0">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLabel" name="label_DXCAddress">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="sizePolicy">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <horstretch>0</horstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <verstretch>0</verstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </sizepolicy>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Address:</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="0" column="5">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLabel" name="label_DXCPort">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="sizePolicy">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <horstretch>0</horstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <verstretch>0</verstretch>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </sizepolicy>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Port:</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="0" column="6">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLineEdit" name="lineEdit_DXCPort">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>7300</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="0" column="1" colspan="4">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLineEdit" name="lineEdit_DXCAddress">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>127.0.0.1</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="1" column="4">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLineEdit" name="lineEdit_DXCSpottimeout">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>10</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="2" column="4">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLineEdit" name="lineEdit_DXCUSername">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>nocall</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="3" column="4">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QPushButton" name="pushButton_DXCDisconnect">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="enabled">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <bool>false</bool>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Disconnect</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="3" column="6">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QPushButton" name="pushButton_DXCConnect">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Connect</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="1" column="5">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLabel" name="label_DXCFilter">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="text">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>Filter:</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="1" column="6">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QLineEdit" name="lineEdit_DXCFilter">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="placeholderText">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string>ex. CW or RTTY</string>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </layout>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <item row="1" column="0">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <widget class="QPlainTextEdit" name="plainTextEdit_DXCMonitor">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="font">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <font>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <pointsize>10</pointsize>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </font>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="documentTitle">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="readOnly">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <bool>true</bool>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="plainText">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <string/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="textInteractionFlags">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <set>Qt::NoTextInteraction</set>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="maximumBlockCount">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <number>240</number>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <property name="toolTipDuration" stdset="0">
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <number>-3</number>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </property>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </item>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </layout>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ </widget>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <resources/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ <connections/>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++</ui>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dxc_spots.cpp src/qtgui/dxc_spots.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..0932b8d
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dxc_spots.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,107 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * http://gqrx.dk/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with Gqrx; see the file COPYING. If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <Qt>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QFile>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QStringList>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QTextStream>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QString>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QSet>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <algorithm>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dxc_spots.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <wchar.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DXCSpots* DXCSpots::m_pThis = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DXCSpots::DXCSpots()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXCSpots::create()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_pThis = new DXCSpots;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++DXCSpots& DXCSpots::Get()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return *m_pThis;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXCSpots::add(DXCSpotInfo &info)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.time = QTime::currentTime();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // check only callsign, so if present remove and re-append
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // if check also frequency we can only change the time
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (m_DXCSpotList.contains(info))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DXCSpotList.removeAt(m_DXCSpotList.indexOf(info));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DXCSpotList.append(info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::stable_sort(m_DXCSpotList.begin(),m_DXCSpotList.end());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ emit( DXCSpotsChanged() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXCSpots::checkSpotTimeout()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < m_DXCSpotList.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if ( m_DXCSpotTimeout < m_DXCSpotList[i].time.secsTo(QTime::currentTime() ))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DXCSpotList.removeAt(i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::stable_sort(m_DXCSpotList.begin(),m_DXCSpotList.end());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ emit( DXCSpotsChanged() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void DXCSpots::remove(int index)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DXCSpotList.removeAt(index);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ emit( DXCSpotsChanged() );
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++QList<DXCSpotInfo> DXCSpots::getDXCSpotsInRange(qint64 low, qint64 high)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpotInfo info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.frequency=low;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<DXCSpotInfo>::const_iterator lb = std::lower_bound(m_DXCSpotList.begin(), m_DXCSpotList.end(), info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ info.frequency=high;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<DXCSpotInfo>::const_iterator ub = std::upper_bound(m_DXCSpotList.begin(), m_DXCSpotList.end(), info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<DXCSpotInfo> found;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while (lb != ub)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const DXCSpotInfo& info = *lb;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //if(info.IsActive())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ found.append(info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ lb++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return found;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++const QColor DXCSpotInfo::GetColor() const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return DXCSpotInfo::color;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/dxc_spots.h src/qtgui/dxc_spots.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+new file mode 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 0000000..c7b0d00
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/dxc_spots.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -0,0 +1,91 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/* -*- c++ -*- */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * http://gqrx.dk/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Copyright 2013 Christian Lindner DL2VCL, Stefano Leucci.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is free software; you can redistribute it and/or modify
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * it under the terms of the GNU General Public License as published by
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation; either version 3, or (at your option)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * any later version.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Gqrx is distributed in the hope that it will be useful,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * GNU General Public License for more details.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * You should have received a copy of the GNU General Public License
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * along with Gqrx; see the file COPYING. If not, write to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * the Free Software Foundation, Inc., 51 Franklin Street,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ * Boston, MA 02110-1301, USA.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#ifndef DXC_SPOTS_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define DXC_SPOTS_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QtGlobal>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QObject>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QString>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QMap>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QList>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QStringList>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QColor>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <QTime>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++struct DXCSpotInfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ qint64 frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QTime time;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QColor color;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpotInfo()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ this->frequency = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ this->time = QTime::currentTime();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ this->color=(Qt::lightGray);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool operator<(const DXCSpotInfo &other) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return frequency < other.frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool operator==(const DXCSpotInfo &other) const
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // we check only the name because frequency can change a bit
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // not good for multi-operator with the case callsign
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return name == other.name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ const QColor GetColor() const;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++class DXCSpots : public QObject
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Q_OBJECT
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // This is a Singleton Class now because you can not send qt-signals from static functions.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static void create();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static DXCSpots& Get();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void add(DXCSpotInfo& info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void checkSpotTimeout();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void remove(int index);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void setSpotTimeout(int i) {m_DXCSpotTimeout = i * 60;}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpotInfo& getDXCSpot(int i) { return m_DXCSpotList[i]; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<DXCSpotInfo> getDXCSpotsInRange(qint64 low, qint64 high);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //int lowerBound(qint64 low);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ //int upperBound(qint64 high);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpots(); // Singleton Constructor is private.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<DXCSpotInfo> m_DXCSpotList;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int m_DXCSpotTimeout;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static DXCSpots* m_pThis;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++signals:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void DXCSpotsChanged(void);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif // DXC_SPOTS_H
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/freqctrl.cpp src/qtgui/freqctrl.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index ed419ed..976cc5e 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/freqctrl.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/freqctrl.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -484,6 +484,7 @@ void CFreqCtrl::keyPressEvent(QKeyEvent *event)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // call base class if dont over ride key
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool fSkipMsg = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ qint64 tmp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ uint8_t position = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // qDebug() <<event->key();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -849,3 +850,16 @@ void CFreqCtrl::cursorEnd()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ center()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void CFreqCtrl::cursorTo(uint8_t position)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cursor().setPos(mapToGlobal(m_DigitInfo[position].dQRect.center()));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void CFreqCtrl::setFrequencyFocus()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ uint8_t position = floor(log10(m_freq));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ position = (uint8_t)fmax(position, 4); // restrict min to 100s of kHz
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ cursorTo(position);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/freqctrl.h src/qtgui/freqctrl.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 08143ab..38dc92c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/freqctrl.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/freqctrl.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -56,6 +56,7 @@ signals:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ public slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setFrequency(qint64 freq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void setFrequencyFocus();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ protected:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void paintEvent(QPaintEvent *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -77,6 +78,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void clearFreq();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void cursorHome();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void cursorEnd();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void cursorTo(uint8_t position);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void moveCursorLeft();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void moveCursorRight();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool inRect(QRect &rect, QPoint &point);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/plotter.cpp src/qtgui/plotter.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index a9d9cff..aaf5950 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/plotter.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/plotter.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -64,7 +64,9 @@ int gettimeofday(struct timeval * tp, struct timezone * tzp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <QtGlobal>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <QToolTip>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "plotter.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "bandplan.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "bookmarks.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include "dxc_spots.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // Comment out to enable plotter debug messages
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ //#define PLOTTER_DEBUG
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -84,6 +86,9 @@ int gettimeofday(struct timeval * tp, struct timezone * tzp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #define PLOTTER_FILTER_BOX_COLOR 0xFFA0A0A4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // FIXME: Should cache the QColors also
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define HOR_MARGIN 5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define VER_MARGIN 5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static inline bool val_is_out_of_range(float val, float min, float max)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return (val < min || val > max);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -146,7 +151,9 @@ CPlotter::CPlotter(QWidget *parent) : QFrame(parent)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_FilterBoxEnabled = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_CenterLineEnabled = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_BandPlanEnabled = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_BookmarksEnabled = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DXCSpotsEnabled = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_Span = 96000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_SampleFreq = 96000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -168,6 +175,7 @@ CPlotter::CPlotter(QWidget *parent) : QFrame(parent)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_Percent2DScreen = 35; //percent of screen used for 2D display
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_VdivDelta = 30;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_HdivDelta = 70;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_BandPlanHeight = 22;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_FreqDigits = 3;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -214,17 +222,20 @@ void CPlotter::mouseMoveEvent(QMouseEvent* event)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool onTag = false;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if(pt.y() < 15 * 10) // FIXME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for(int i = 0; i < m_BookmarkTags.size() && !onTag; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(m_BookmarksEnabled || m_DXCSpotsEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (m_BookmarkTags[i].first.contains(event->pos()))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- onTag = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for(int i = 0; i < Taglist.size() && !onTag; i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (Taglist[i].first.contains(event->pos()))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ onTag = true;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // if no mouse button monitor grab regions and change cursor icon
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (onTag)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ setCursor(QCursor(Qt::PointingHandCursor));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- m_CursorCaptured = BOOKMARK;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_CursorCaptured = TAG;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (isPointCloseTo(pt.x(), m_DemodFreqX, m_CursorCaptureDelta))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -286,10 +297,20 @@ void CPlotter::mouseMoveEvent(QMouseEvent* event)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_CursorCaptured = NOCAP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (m_TooltipsEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- QToolTip::showText(event->globalPos(),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- QString("F: %1 kHz")
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- .arg(freqFromX(pt.x())/1.e3f, 0, 'f', 3),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ qint64 hoverFrequency = freqFromX(pt.x());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString toolTipText = QString("F: %1 kHz").arg(hoverFrequency/1.e3f, 0, 'f', 3);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QFontMetrics metrics(m_Font);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int bandTopY = m_OverlayPixmap.height() - metrics.height() - 2 * VER_MARGIN - m_BandPlanHeight;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BandInfo> hoverBands = BandPlan::Get().getBandsEncompassing(hoverFrequency);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(m_BandPlanEnabled && pt.y() > bandTopY && hoverBands.size() > 0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ toolTipText.append("\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < hoverBands.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ toolTipText.append("\n" + hoverBands[i].name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QToolTip::showText(event->globalPos(), toolTipText, this);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_GrabPosition = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -687,13 +708,13 @@ void CPlotter::mousePressEvent(QMouseEvent * event)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ resetHorizontalZoom();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- else if (m_CursorCaptured == BOOKMARK)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else if (m_CursorCaptured == TAG)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for (int i = 0; i < m_BookmarkTags.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < Taglist.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (m_BookmarkTags[i].first.contains(event->pos()))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (Taglist[i].first.contains(event->pos()))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- m_DemodCenterFreq = m_BookmarkTags[i].second;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DemodCenterFreq = Taglist[i].second;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ emit newDemodFreq(m_DemodCenterFreq, m_DemodCenterFreq - m_CenterFreq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1271,8 +1292,7 @@ void CPlotter::drawOverlay()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ painter.setBrush(Qt::SolidPattern);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ painter.fillRect(0, 0, w, h, QColor(PLOTTER_BGD_COLOR));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#define HOR_MARGIN 5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#define VER_MARGIN 5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BookmarkInfo> tags;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // X and Y axis areas
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_YAxisWidth = metrics.width("XXXX") + 2 * HOR_MARGIN;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1281,25 +1301,47 @@ void CPlotter::drawOverlay()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int xAxisTop = h - xAxisHeight;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int fLabelTop = xAxisTop + VER_MARGIN;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (m_BookmarksEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (m_BookmarksEnabled || m_DXCSpotsEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- m_BookmarkTags.clear();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Taglist.clear();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const QFontMetrics fm(painter.font());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const int fontHeight = fm.ascent() + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const int slant = 5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static const int levelHeight = fontHeight + 5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const int nLevels = h / (levelHeight + slant);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- QList<BookmarkInfo> bookmarks = Bookmarks::Get().getBookmarksInRange(m_CenterFreq + m_FftCenter - m_Span / 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (m_BookmarksEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tags = Bookmarks::Get().getBookmarksInRange(m_CenterFreq + m_FftCenter - m_Span / 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_CenterFreq + m_FftCenter + m_Span / 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tags.clear();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (m_DXCSpotsEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<DXCSpotInfo> dxcspots = DXCSpots::Get().getDXCSpotsInRange(m_CenterFreq + m_FftCenter - m_Span / 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_CenterFreq + m_FftCenter + m_Span / 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QListIterator<DXCSpotInfo> iter(dxcspots);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while(iter.hasNext())
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ BookmarkInfo tempDXCSpot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ DXCSpotInfo IterDXCSpot = iter.next();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tempDXCSpot.name = IterDXCSpot.name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tempDXCSpot.frequency = IterDXCSpot.frequency;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tags.append(tempDXCSpot);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ std::stable_sort(tags.begin(),tags.end());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QVector<int> tagEnd(nLevels + 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for (int i = 0; i < bookmarks.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < tags.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- x = xFromFreq(bookmarks[i].frequency);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ x = xFromFreq(tags[i].frequency);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #if defined(_WIN16) || defined(_WIN32) || defined(_WIN64)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int nameWidth = fm.width(bookmarks[i].name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- int nameWidth = fm.boundingRect(bookmarks[i].name).width();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int nameWidth = fm.boundingRect(tags[i].name).width();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int level = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1319,9 +1361,9 @@ void CPlotter::drawOverlay()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const auto levelNHeightBottom = levelNHeight + fontHeight;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const auto levelNHeightBottomSlant = levelNHeightBottom + slant;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- m_BookmarkTags.append(qMakePair<QRect, qint64>(QRect(x, levelNHeight, nameWidth + slant, fontHeight), bookmarks[i].frequency));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ Taglist.append(qMakePair<QRect, qint64>(QRect(x, level * levelHeight, nameWidth + slant, fontHeight), tags[i].frequency));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- QColor color = QColor(bookmarks[i].GetColor());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QColor color = QColor(tags[i].GetColor());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ color.setAlpha(0x60);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // Vertical line
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ painter.setPen(QPen(color, 1, Qt::DashLine));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1340,10 +1382,85 @@ void CPlotter::drawOverlay()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ painter.setPen(QPen(color, 2, Qt::SolidLine));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ painter.drawText(x + slant, levelNHeight, nameWidth,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fontHeight, Qt::AlignVCenter | Qt::AlignHCenter,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- bookmarks[i].name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tags[i].name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (m_BandPlanEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<BandInfo> bands = BandPlan::Get().getBandsInRange(m_CenterFreq + m_FftCenter - m_Span / 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_CenterFreq + m_FftCenter + m_Span / 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < bands.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int band_left = xFromFreq(bands[i].minFrequency);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int band_right = xFromFreq(bands[i].maxFrequency);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int band_width = band_right - band_left;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rect.setRect(band_left, xAxisTop - m_BandPlanHeight, band_width, m_BandPlanHeight);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.fillRect(rect, bands[i].color);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QString band_label = bands[i].name + " (" + bands[i].modulation + ")";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int textWidth = metrics.width(band_label);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (band_left < w && band_width > textWidth + 20)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.setOpacity(1.0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ rect.setRect(band_left, xAxisTop - m_BandPlanHeight, band_width, metrics.height());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.setPen(QColor(PLOTTER_TEXT_COLOR));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.drawText(rect, Qt::AlignCenter, band_label);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (m_DXCSpotsEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DXCSpotTags.clear();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const QFontMetrics fm(painter.font());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const int fontHeight = fm.ascent() + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const int slant = 5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const int levelHeight = fontHeight + 5;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ static const int nLevels = 10;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList<DXCSpotInfo> dxcspots = DXCSpots::Get().getDXCSpotsInRange(m_CenterFreq + m_FftCenter - m_Span / 2,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_CenterFreq + m_FftCenter + m_Span / 2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int tagEnd[nLevels] = {0};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ for (int i = 0; i < dxcspots.size(); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ x = xFromFreq(dxcspots[i].frequency);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#if defined(_WIN16) || defined(_WIN32) || defined(_WIN64)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int nameWidth = fm.width(dxcspots[i].name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int nameWidth = fm.boundingRect(dxcspots[i].name).width();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int level = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ while(level < nLevels && tagEnd[level] > x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ level++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if(level == nLevels)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ level = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ tagEnd[level] = x + nameWidth + slant - 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_DXCSpotTags.append(qMakePair<QRect, qint64>(QRect(x, level * levelHeight, nameWidth + slant, fontHeight), dxcspots[i].frequency));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QColor color = QColor(dxcspots[i].GetColor());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ color.setAlpha(0x60);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Vertical line
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.setPen(QPen(color, 1, Qt::DashLine));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.drawLine(x, level * levelHeight + fontHeight + slant, x, xAxisTop);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Horizontal line
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.setPen(QPen(color, 1, Qt::SolidLine));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.drawLine(x + slant, level * levelHeight + fontHeight,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ x + nameWidth + slant - 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ level * levelHeight + fontHeight);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ // Diagonal line
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.drawLine(x + 1, level * levelHeight + fontHeight + slant - 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ x + slant - 1, level * levelHeight + fontHeight + 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ color.setAlpha(0xFF);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.setPen(QPen(color, 2, Qt::SolidLine));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ painter.drawText(x + slant, level * levelHeight, nameWidth,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ fontHeight, Qt::AlignVCenter | Qt::AlignHCenter,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ dxcspots[i].name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++*/
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (m_CenterLineEnabled)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ x = xFromFreq(m_CenterFreq);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1515,7 +1632,7 @@ void CPlotter::makeFrequencyStrs()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// Convert from screen coordinate to frequency
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// Convert from frequency to screen coordinate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int CPlotter::xFromFreq(qint64 freq)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int w = m_OverlayPixmap.width();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1528,7 +1645,7 @@ int CPlotter::xFromFreq(qint64 freq)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return x;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-// Convert from frequency to screen coordinate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++// Convert from screen coordinate to frequency
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ qint64 CPlotter::freqFromX(int x)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int w = m_OverlayPixmap.width();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -1674,6 +1791,12 @@ void CPlotter::setPeakDetection(bool enabled, float c)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ m_PeakDetection = c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++void CPlotter::toggleBandPlan(bool state)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ m_BandPlanEnabled = state;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ updateOverlay();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void CPlotter::calcDivSize (qint64 low, qint64 high, int divswanted, qint64 &adjlow, qint64 &step, int& divs)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #ifdef PLOTTER_DEBUG
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/qtgui/plotter.h src/qtgui/plotter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index f4cb362..aa70fad 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/qtgui/plotter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/qtgui/plotter.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -38,6 +38,8 @@ public:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setCenterLineEnabled(bool enabled) { m_CenterLineEnabled = enabled; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setTooltipsEnabled(bool enabled) { m_TooltipsEnabled = enabled; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setBookmarksEnabled(bool enabled) { m_BookmarksEnabled = enabled; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void setDXCSpotsEnabled(bool enabled) { m_DXCSpotsEnabled = enabled; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void setBandPlanEnabled(bool enabled) { m_BandPlanEnabled = enabled; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setNewFftData(float *fftData, int size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setNewFftData(float *fftData, float *wfData, int size);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -146,6 +148,7 @@ public slots:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setPandapterRange(float min, float max);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setWaterfallRange(float min, float max);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setPeakDetection(bool enabled, float c);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void toggleBandPlan(bool state);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void updateOverlay();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void setPercent2DScreen(int percent)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -172,7 +175,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ RIGHT,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ YAXIS,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ XAXIS,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- BOOKMARK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ TAG
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ };
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ void drawOverlay();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -223,8 +226,10 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ qint64 m_FreqPerDiv;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool m_CenterLineEnabled; /*!< Distinguish center line. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool m_FilterBoxEnabled; /*!< Draw filter box. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- bool m_TooltipsEnabled; /*!< Tooltips enabled */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool m_TooltipsEnabled; /*!< Tooltips enabled */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool m_BandPlanEnabled; /*!< Show/hide band plan on spectrum */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ bool m_BookmarksEnabled; /*!< Show/hide bookmarks on spectrum */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ bool m_DXCSpotsEnabled; /*!< Show/hide DXC Spots on spectrum */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int m_DemodHiCutFreq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int m_DemodLowCutFreq;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int m_DemodFreqX; //screen coordinate x position
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -261,6 +266,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QFont m_Font; /*!< Font used for plotter (system font) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int m_HdivDelta; /*!< Minimum distance in pixels between two horizontal grid lines (vertical division). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int m_VdivDelta; /*!< Minimum distance in pixels between two vertical grid lines (horizontal division). */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ int m_BandPlanHeight; /*!< Height in pixels of band plan (if enabled) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ quint32 m_LastSampleRate;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -270,7 +276,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ float m_PeakDetection;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ QMap<int,int> m_Peaks;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- QList< QPair<QRect, qint64> > m_BookmarkTags;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ QList< QPair<QRect, qint64> > Taglist;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ // Waterfall averaging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ quint64 tlast_wf_ms; // last time waterfall has been updated
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/receivers/nbrx.cpp src/receivers/nbrx.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 9370c70..fa1507c 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/receivers/nbrx.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/receivers/nbrx.cpp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -63,8 +63,7 @@ nbrx::nbrx(float quad_rate, float audio_rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ demod = demod_fm;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(self(), 0, iq_resamp, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(iq_resamp, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(nb, 0, filter, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(iq_resamp, 0, filter, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(filter, 0, meter, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(filter, 0, sql, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(sql, 0, agc, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -72,15 +71,16 @@ nbrx::nbrx(float quad_rate, float audio_rate)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (audio_rr0)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(audio_rr0, 0, self(), 0); // left channel
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(audio_rr0, 0, self(), 1); // right channel
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -211,15 +211,17 @@ void nbrx::set_demod(int rx_demod)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (current_demod == NBRX_DEMOD_NONE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- disconnect(demod, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- disconnect(demod, 1, audio_rr1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(nb, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(nb, 1, audio_rr1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ disconnect(audio_rr0, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ disconnect(audio_rr1, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- disconnect(demod, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(nb, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ disconnect(audio_rr0, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ disconnect(audio_rr0, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -229,13 +231,15 @@ void nbrx::set_demod(int rx_demod)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (current_demod == NBRX_DEMOD_NONE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- disconnect(demod, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- disconnect(demod, 1, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(nb, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(nb, 1, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- disconnect(demod, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- disconnect(demod, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(nb, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ disconnect(nb, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -268,15 +272,17 @@ void nbrx::set_demod(int rx_demod)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (d_demod == NBRX_DEMOD_NONE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 1, audio_rr1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 1, audio_rr1, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(audio_rr0, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(audio_rr1, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, audio_rr0, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(audio_rr0, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ connect(audio_rr0, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -286,13 +292,15 @@ void nbrx::set_demod(int rx_demod)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (d_demod == NBRX_DEMOD_NONE)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 1, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 1, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- connect(demod, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(demod, 0, nb, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, self(), 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ connect(nb, 0, self(), 1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git src/receivers/nbrx.h src/receivers/nbrx.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 1aa845c..a57909d 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- src/receivers/nbrx.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ src/receivers/nbrx.h
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -36,6 +36,7 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "dsp/rx_demod_am.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ //#include "dsp/resampler_ff.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include "dsp/resampler_xx.h"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#include <gnuradio/blocks/float_to_complex.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ class nbrx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -122,6 +123,7 @@ private:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr::analog::simple_squelch_cc::sptr sql; /*!< Squelch. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr::blocks::complex_to_float::sptr demod_raw; /*!< Raw I/Q passthrough. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ gr::blocks::complex_to_real::sptr demod_ssb; /*!< SSB demodulator. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx_demod_fm_sptr demod_fm; /*!< FM demodulator. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ rx_demod_am_sptr demod_am; /*!< AM demodulator. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ resampler_ff_sptr audio_rr0; /*!< Audio resampler. */
</span></pre><pre style='margin:0'>
</pre>