mirror of
https://github.com/gqrx-sdr/gqrx.git
synced 2024-09-21 18:57:10 +00:00
200 lines
6.0 KiB
C++
200 lines
6.0 KiB
C++
/* -*- c++ -*- */
|
|
/*
|
|
* Copyright 2011 Alexandru Csete OZ9AEC.
|
|
*
|
|
* Gqrx is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3, or (at your option)
|
|
* any later version.
|
|
*
|
|
* Gqrx is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Gqrx; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
#include <math.h>
|
|
#include <gr_io_signature.h>
|
|
#include <gr_complex.h>
|
|
#include <dsp/rx_agc_xx.h>
|
|
|
|
|
|
rx_agc_cc_sptr make_rx_agc_cc(double sample_rate, bool agc_on, int threshold,
|
|
int manual_gain, int slope, int decay, bool use_hang)
|
|
{
|
|
return gnuradio::get_initial_sptr(new rx_agc_cc(sample_rate, agc_on, threshold,
|
|
manual_gain, slope, decay,
|
|
use_hang));
|
|
}
|
|
|
|
|
|
/*! \brief Create receiver AGC object.
|
|
*
|
|
* Use make_rx_agc_cc() instead.
|
|
*/
|
|
rx_agc_cc::rx_agc_cc(double sample_rate, bool agc_on, int threshold,
|
|
int manual_gain, int slope, int decay, bool use_hang)
|
|
: gr_sync_block ("rx_agc_cc",
|
|
gr_make_io_signature(1, 1, sizeof(gr_complex)),
|
|
gr_make_io_signature(1, 1, sizeof(gr_complex))),
|
|
d_sample_rate(sample_rate),
|
|
d_agc_on(agc_on),
|
|
d_threshold(threshold),
|
|
d_manual_gain(manual_gain),
|
|
d_slope(slope),
|
|
d_decay(decay),
|
|
d_use_hang(use_hang)
|
|
{
|
|
d_agc = new CAgc();
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
|
|
rx_agc_cc::~rx_agc_cc()
|
|
{
|
|
delete d_agc;
|
|
}
|
|
|
|
|
|
/*! \brief Receiver AGC work method.
|
|
* \param mooutput_items
|
|
* \param input_items
|
|
* \param output_items
|
|
*/
|
|
int rx_agc_cc::work(int noutput_items,
|
|
gr_vector_const_void_star &input_items,
|
|
gr_vector_void_star &output_items)
|
|
{
|
|
const gr_complex *in = (const gr_complex *) input_items[0];
|
|
gr_complex *out = (gr_complex *) output_items[0];
|
|
int i;
|
|
|
|
// lock mutex
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
|
|
for (i = 0; i < noutput_items; i++) {
|
|
ib[i].im = in[i].imag();
|
|
ib[i].re = in[i].real();
|
|
}
|
|
|
|
d_agc->ProcessData(noutput_items, &ib[0], &ob[0]);
|
|
|
|
for (i = 0; i < noutput_items; i++) {
|
|
out[i].real() = ob[i].re;
|
|
out[i].imag() = ob[i].im;
|
|
}
|
|
|
|
return noutput_items;
|
|
}
|
|
|
|
|
|
/*! \brief Enable or disable AGC.
|
|
* \param agc_on Whether AGC should be endabled.
|
|
*
|
|
* When AGC is disabled a fixed gain is used.
|
|
*
|
|
* \sa set_manual_gain()
|
|
*/
|
|
void rx_agc_cc::set_agc_on(bool agc_on)
|
|
{
|
|
if (agc_on != d_agc_on) {
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
d_agc_on = agc_on;
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
}
|
|
|
|
/*! \brief Set AGC sample rate.
|
|
* \param sample_rate The sample rate.
|
|
*
|
|
* The AGC uses knowledge about the sample rate to calculate various delays and
|
|
* time constants.
|
|
*/
|
|
void rx_agc_cc::set_sample_rate(double sample_rate)
|
|
{
|
|
if (sample_rate != d_sample_rate) {
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
d_sample_rate = sample_rate;
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
}
|
|
|
|
/*! \brief Set new AGC threshold.
|
|
* \param threshold The new threshold between -160 and 0dB.
|
|
*
|
|
* The threshold specifies AGC "knee" in dB when the AGC is active.
|
|
*/
|
|
void rx_agc_cc::set_threshold(int threshold)
|
|
{
|
|
if ((threshold != d_threshold) && (threshold >= -160) && (threshold <= 0)) {
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
d_threshold = threshold;
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
}
|
|
|
|
/*! \brief Set new manual gain.
|
|
* \param gain The new manual gain between 0 and 100dB.
|
|
*
|
|
* The manual gain is used when AGC is switched off.
|
|
*
|
|
* \sa set_agc_on()
|
|
*/
|
|
void rx_agc_cc::set_manual_gain(int gain)
|
|
{
|
|
if ((gain != d_manual_gain) && (gain >= 0) && (gain <= 100)) {
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
d_manual_gain = gain;
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
}
|
|
|
|
/*! \brief Set AGC slope factor.
|
|
* \param slope The new slope factor between 0 and 10dB.
|
|
*
|
|
* The slope factor specifies dB reduction in output at knee from maximum output level
|
|
*/
|
|
void rx_agc_cc::set_slope(int slope)
|
|
{
|
|
if (slope != d_slope) {
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
d_slope = slope;
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
}
|
|
|
|
/*! \brief Set AGC decay time.
|
|
* \param decay The new AGC decay time between 20 to 5000 ms.
|
|
*/
|
|
void rx_agc_cc::set_decay(int decay)
|
|
{
|
|
if (decay != d_decay) {
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
d_decay = decay;
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
}
|
|
|
|
/*! \brief Enable/disable AGC hang.
|
|
* \param use_hang Whether to use hang or not.
|
|
*/
|
|
void rx_agc_cc::set_use_hang(bool use_hang)
|
|
{
|
|
if (use_hang != d_use_hang) {
|
|
boost::mutex::scoped_lock lock(d_mutex);
|
|
d_use_hang = use_hang;
|
|
d_agc->SetParameters(d_agc_on, d_use_hang, d_threshold, d_manual_gain,
|
|
d_slope, d_decay, d_sample_rate);
|
|
}
|
|
}
|