mirror of
https://github.com/gqrx-sdr/gqrx.git
synced 2024-09-21 18:57:10 +00:00
Add input decimator to receiver.
This commit is contained in:
parent
fa0c49445c
commit
9c06cb58b8
@ -87,7 +87,7 @@ MainWindow::MainWindow(const QString cfgfile, bool edit_conf, QWidget *parent) :
|
||||
d_filter_shape = receiver::FILTER_SHAPE_NORMAL;
|
||||
|
||||
/* create receiver object */
|
||||
rx = new receiver("", "");
|
||||
rx = new receiver("", "", 1);
|
||||
rx->set_rf_freq(144500000.0f);
|
||||
|
||||
// remote controller
|
||||
@ -367,7 +367,9 @@ MainWindow::~MainWindow()
|
||||
*/
|
||||
bool MainWindow::loadConfig(const QString cfgfile, bool check_crash)
|
||||
{
|
||||
double actual_rate;
|
||||
qint64 int64_val;
|
||||
int int_val;
|
||||
bool bool_val;
|
||||
bool conf_ok = false;
|
||||
bool conv_ok;
|
||||
@ -453,10 +455,10 @@ bool MainWindow::loadConfig(const QString cfgfile, bool check_crash)
|
||||
QString outdev = m_settings->value("output/device", "").toString();
|
||||
rx->set_output_device(outdev.toStdString());
|
||||
|
||||
int sr = m_settings->value("input/sample_rate", 0).toInt(&conv_ok);
|
||||
if (conv_ok && (sr > 0))
|
||||
int_val = m_settings->value("input/sample_rate", 0).toInt(&conv_ok);
|
||||
if (conv_ok && (int_val > 0))
|
||||
{
|
||||
double actual_rate = rx->set_input_rate(sr);
|
||||
actual_rate = rx->set_input_rate(int_val);
|
||||
|
||||
if (actual_rate == 0)
|
||||
{
|
||||
@ -472,19 +474,40 @@ bool MainWindow::loadConfig(const QString cfgfile, bool check_crash)
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
|
||||
actual_rate = sr;
|
||||
actual_rate = int_val;
|
||||
}
|
||||
|
||||
qDebug() << "Requested sample rate:" << sr;
|
||||
qDebug() << "Requested sample rate:" << int_val;
|
||||
qDebug() << "Actual sample rate :" << QString("%1").arg(actual_rate, 0, 'f', 6);
|
||||
uiDockRxOpt->setFilterOffsetRange((qint64)(0.9*actual_rate));
|
||||
ui->plotter->setSampleRate(actual_rate);
|
||||
ui->plotter->setSpanFreq((quint32)actual_rate);
|
||||
|
||||
remote->setBandwidth(sr);
|
||||
iq_tool->setSampleRate(sr);
|
||||
}
|
||||
|
||||
int_val = m_settings->value("input/decimation", 1).toInt(&conv_ok);
|
||||
if (conv_ok && int_val >= 2)
|
||||
{
|
||||
if (rx->set_input_decim(int_val) != int_val)
|
||||
{
|
||||
qDebug() << "Failed to set decimation" << int_val;
|
||||
qDebug() << " actual decimation:" << rx->get_input_decim();
|
||||
}
|
||||
else
|
||||
{
|
||||
// update actual rate
|
||||
actual_rate /= (double)int_val;
|
||||
qDebug() << "Input decimation:" << int_val;
|
||||
qDebug() << "Quadrature rate:" << QString("%1").arg(actual_rate, 0, 'f', 6);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rx->set_input_decim(1);
|
||||
}
|
||||
// update various widget that need a sample rate
|
||||
uiDockRxOpt->setFilterOffsetRange((qint64)(0.9*actual_rate));
|
||||
ui->plotter->setSampleRate(actual_rate);
|
||||
ui->plotter->setSpanFreq((quint32)actual_rate);
|
||||
remote->setBandwidth((qint64)actual_rate);
|
||||
iq_tool->setSampleRate((qint64)actual_rate);
|
||||
|
||||
int64_val = m_settings->value("input/bandwidth", 0).toInt(&conv_ok);
|
||||
if (conv_ok)
|
||||
{
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include "applications/gqrx/receiver.h"
|
||||
#include "dsp/correct_iq_cc.h"
|
||||
#include "dsp/hbf_decim.h"
|
||||
#include "dsp/rx_fft.h"
|
||||
#include "receivers/nbrx.h"
|
||||
#include "receivers/wfmrx.h"
|
||||
@ -49,10 +50,13 @@
|
||||
* @param audio_device Audio output device specifier,
|
||||
* e.g. hw:0 when using ALSA or Portaudio.
|
||||
*/
|
||||
receiver::receiver(const std::string input_device, const std::string audio_device)
|
||||
receiver::receiver(const std::string input_device,
|
||||
const std::string audio_device,
|
||||
unsigned int decimation)
|
||||
: d_running(false),
|
||||
d_input_rate(96000.0),
|
||||
d_audio_rate(48000),
|
||||
d_decim(decimation),
|
||||
d_rf_freq(144800000.0),
|
||||
d_filter_offset(0.0),
|
||||
d_recording_iq(false),
|
||||
@ -77,21 +81,44 @@ receiver::receiver(const std::string input_device, const std::string audio_devic
|
||||
src = osmosdr::source::make(input_device);
|
||||
}
|
||||
|
||||
// input decimator
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
input_decim = make_hbf_decim(d_decim);
|
||||
}
|
||||
catch (std::range_error &e)
|
||||
{
|
||||
std::cout << "Error opening creating input decimator " << d_decim
|
||||
<< ": " << e.what() << std::endl
|
||||
<< "Using decimation 1." << std::endl;
|
||||
d_decim = 1;
|
||||
}
|
||||
|
||||
d_quad_rate = d_input_rate / (double)d_decim;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_quad_rate = d_input_rate;
|
||||
}
|
||||
|
||||
|
||||
// create I/Q sink and close it
|
||||
iq_sink = gr::blocks::file_sink::make(sizeof(gr_complex), "/dev/null", false);
|
||||
iq_sink->set_unbuffered(true);
|
||||
iq_sink->close();
|
||||
|
||||
rx = make_nbrx(d_input_rate, d_audio_rate);
|
||||
lo = gr::analog::sig_source_c::make(d_input_rate, gr::analog::GR_SIN_WAVE,
|
||||
rx = make_nbrx(d_quad_rate, d_audio_rate);
|
||||
lo = gr::analog::sig_source_c::make(d_quad_rate, gr::analog::GR_SIN_WAVE,
|
||||
0.0, 1.0);
|
||||
mixer = gr::blocks::multiply_cc::make();
|
||||
|
||||
iq_swap = make_iq_swap_cc(false);
|
||||
dc_corr = make_dc_corr_cc(d_input_rate, 1.0);
|
||||
iq_fft = make_rx_fft_c(4096u, 0);
|
||||
dc_corr = make_dc_corr_cc(d_quad_rate, 1.0);
|
||||
iq_fft = make_rx_fft_c(8192u, 0);
|
||||
|
||||
audio_fft = make_rx_fft_f(4096u);
|
||||
audio_fft = make_rx_fft_f(8192u);
|
||||
audio_gain0 = gr::blocks::multiply_const_ff::make(0.1);
|
||||
audio_gain1 = gr::blocks::multiply_const_ff::make(0.1);
|
||||
|
||||
@ -183,11 +210,28 @@ void receiver::set_input_device(const std::string device)
|
||||
tb->wait();
|
||||
}
|
||||
|
||||
tb->disconnect(src, 0, iq_swap, 0);
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
tb->disconnect(src, 0, input_decim, 0);
|
||||
tb->disconnect(input_decim, 0, iq_swap, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->disconnect(src, 0, iq_swap, 0);
|
||||
}
|
||||
|
||||
src.reset();
|
||||
src = osmosdr::source::make(device);
|
||||
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
tb->connect(src, 0, input_decim, 0);
|
||||
tb->connect(input_decim, 0, iq_swap, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
}
|
||||
|
||||
if (d_running)
|
||||
tb->start();
|
||||
@ -273,9 +317,10 @@ double receiver::set_input_rate(double rate)
|
||||
d_input_rate = rate;
|
||||
}
|
||||
|
||||
dc_corr->set_sample_rate(d_input_rate);
|
||||
rx->set_quad_rate(d_input_rate);
|
||||
lo->set_sampling_freq(d_input_rate);
|
||||
d_quad_rate = d_input_rate / (double)d_decim;
|
||||
dc_corr->set_sample_rate(d_quad_rate);
|
||||
rx->set_quad_rate(d_quad_rate);
|
||||
lo->set_sampling_freq(d_quad_rate);
|
||||
tb->unlock();
|
||||
|
||||
return d_input_rate;
|
||||
@ -288,6 +333,72 @@ double receiver::get_input_rate(void) const
|
||||
return d_input_rate;
|
||||
}
|
||||
|
||||
/** Set input decimation */
|
||||
unsigned int receiver::set_input_decim(unsigned int decim)
|
||||
{
|
||||
if (decim == d_decim)
|
||||
return d_decim;
|
||||
|
||||
if (d_running)
|
||||
{
|
||||
tb->stop();
|
||||
tb->wait();
|
||||
}
|
||||
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
tb->disconnect(src, 0, input_decim, 0);
|
||||
tb->disconnect(input_decim, 0, iq_swap, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->disconnect(src, 0, iq_swap, 0);
|
||||
}
|
||||
|
||||
input_decim.reset();
|
||||
d_decim = decim;
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
input_decim = make_hbf_decim(d_decim);
|
||||
}
|
||||
catch (std::range_error &e)
|
||||
{
|
||||
std::cout << "Error opening creating input decimator " << d_decim
|
||||
<< ": " << e.what() << std::endl
|
||||
<< "Using decimation 1." << std::endl;
|
||||
d_decim = 1;
|
||||
}
|
||||
|
||||
d_quad_rate = d_input_rate / (double)d_decim;
|
||||
}
|
||||
else
|
||||
{
|
||||
d_quad_rate = d_input_rate;
|
||||
}
|
||||
|
||||
// update quadrature rate
|
||||
dc_corr->set_sample_rate(d_quad_rate);
|
||||
rx->set_quad_rate(d_quad_rate);
|
||||
lo->set_sampling_freq(d_quad_rate);
|
||||
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
tb->connect(src, 0, input_decim, 0);
|
||||
tb->connect(input_decim, 0, iq_swap, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
}
|
||||
|
||||
if (d_running)
|
||||
tb->start();
|
||||
|
||||
return d_decim;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set new analog bandwidth.
|
||||
* @param bw The new bandwidth.
|
||||
@ -991,7 +1102,11 @@ receiver::status receiver::start_iq_recording(const std::string filename)
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->connect(src, 0, iq_sink, 0);
|
||||
if (d_decim >= 2)
|
||||
tb->connect(input_decim, 0, iq_sink, 0);
|
||||
else
|
||||
tb->connect(src, 0, iq_sink, 0);
|
||||
|
||||
d_recording_iq = true;
|
||||
}
|
||||
tb->unlock();
|
||||
@ -1014,7 +1129,12 @@ receiver::status receiver::stop_iq_recording()
|
||||
|
||||
tb->lock();
|
||||
iq_sink->close();
|
||||
tb->disconnect(src, 0, iq_sink, 0);
|
||||
|
||||
if (d_decim >= 2)
|
||||
tb->disconnect(input_decim, 0, iq_sink, 0);
|
||||
else
|
||||
tb->disconnect(src, 0, iq_sink, 0);
|
||||
|
||||
tb->unlock();
|
||||
d_recording_iq = false;
|
||||
|
||||
@ -1102,7 +1222,15 @@ void receiver::connect_all(rx_chain type)
|
||||
switch (type)
|
||||
{
|
||||
case RX_CHAIN_NONE:
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
tb->connect(src, 0, input_decim, 0);
|
||||
tb->connect(input_decim, 0, iq_swap, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
}
|
||||
if (d_dc_cancel)
|
||||
{
|
||||
tb->connect(iq_swap, 0, dc_corr, 0);
|
||||
@ -1118,9 +1246,17 @@ void receiver::connect_all(rx_chain type)
|
||||
if (rx->name() != "NBRX")
|
||||
{
|
||||
rx.reset();
|
||||
rx = make_nbrx(d_input_rate, d_audio_rate);
|
||||
rx = make_nbrx(d_quad_rate, d_audio_rate);
|
||||
}
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
tb->connect(src, 0, input_decim, 0);
|
||||
tb->connect(input_decim, 0, iq_swap, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
}
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
if (d_dc_cancel)
|
||||
{
|
||||
tb->connect(iq_swap, 0, dc_corr, 0);
|
||||
@ -1146,9 +1282,17 @@ void receiver::connect_all(rx_chain type)
|
||||
if (rx->name() != "WFMRX")
|
||||
{
|
||||
rx.reset();
|
||||
rx = make_wfmrx(d_input_rate, d_audio_rate);
|
||||
rx = make_wfmrx(d_quad_rate, d_audio_rate);
|
||||
}
|
||||
if (d_decim >= 2)
|
||||
{
|
||||
tb->connect(src, 0, input_decim, 0);
|
||||
tb->connect(input_decim, 0, iq_swap, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
}
|
||||
tb->connect(src, 0, iq_swap, 0);
|
||||
if (d_dc_cancel)
|
||||
{
|
||||
tb->connect(iq_swap, 0, dc_corr, 0);
|
||||
@ -1177,7 +1321,10 @@ void receiver::connect_all(rx_chain type)
|
||||
// reconnect recorders and sniffers
|
||||
if (d_recording_iq)
|
||||
{
|
||||
tb->connect(src, 0, iq_sink, 0);
|
||||
if (d_decim >= 2)
|
||||
tb->connect(input_decim, 0, iq_sink, 0);
|
||||
else
|
||||
tb->connect(src, 0, iq_sink, 0);
|
||||
}
|
||||
|
||||
if (d_recording_wav)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "dsp/correct_iq_cc.h"
|
||||
#include "dsp/hbf_decim.h"
|
||||
#include "dsp/rx_noise_blanker_cc.h"
|
||||
#include "dsp/rx_filter.h"
|
||||
#include "dsp/rx_meter.h"
|
||||
@ -103,7 +104,9 @@ public:
|
||||
FILTER_SHAPE_SHARP = 2 /*!< Sharp: Transition band is TBD of width. */
|
||||
};
|
||||
|
||||
receiver(const std::string input_device="", const std::string audio_device="");
|
||||
receiver(const std::string input_device="",
|
||||
const std::string audio_device="",
|
||||
unsigned int decimation=1);
|
||||
~receiver();
|
||||
|
||||
void start();
|
||||
@ -117,6 +120,9 @@ public:
|
||||
double set_input_rate(double rate);
|
||||
double get_input_rate(void) const;
|
||||
|
||||
unsigned int set_input_decim(unsigned int decim);
|
||||
unsigned int get_input_decim(void) const { return d_decim; }
|
||||
|
||||
double set_analog_bandwidth(double bw);
|
||||
double get_analog_bandwidth(void) const;
|
||||
|
||||
@ -212,7 +218,9 @@ private:
|
||||
private:
|
||||
bool d_running; /*!< Whether receiver is running or not. */
|
||||
double d_input_rate; /*!< Input sample rate. */
|
||||
double d_quad_rate; /*!< Quadrature rate (input_rate / decim) */
|
||||
double d_audio_rate; /*!< Audio output rate. */
|
||||
unsigned int d_decim; /*!< input decimation. */
|
||||
double d_rf_freq; /*!< Current RF frequency. */
|
||||
double d_filter_offset; /*!< Current filter offset */
|
||||
bool d_recording_iq; /*!< Whether we are recording I/Q file. */
|
||||
@ -230,6 +238,7 @@ private:
|
||||
gr::top_block_sptr tb; /*!< The GNU Radio top block. */
|
||||
|
||||
osmosdr::source::sptr src; /*!< Real time I/Q source. */
|
||||
hbf_decim_sptr input_decim; /*!< Input decimator. */
|
||||
receiver_base_cf_sptr rx; /*!< receiver. */
|
||||
|
||||
dc_corr_cc_sptr dc_corr; /*!< DC corrector block. */
|
||||
|
Loading…
Reference in New Issue
Block a user