3 * Copyright 2006 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
27 #include <gr_feedforward_agc_cc.h>
28 #include <gr_io_signature.h>
31 gr_feedforward_agc_cc_sptr
32 gr_make_feedforward_agc_cc(int nsamples, float reference)
34 return gr_feedforward_agc_cc_sptr(new gr_feedforward_agc_cc (nsamples, reference));
37 gr_feedforward_agc_cc::gr_feedforward_agc_cc (int nsamples, float reference)
38 : gr_sync_block ("gr_feedforward_agc_cc",
39 gr_make_io_signature (1, 1, sizeof (gr_complex)),
40 gr_make_io_signature (1, 1, sizeof (gr_complex))),
41 d_nsamples(nsamples), d_reference(reference)
44 throw std::invalid_argument("gr_feedforward_agc_cc: nsamples must be >= 1");
46 set_history(nsamples);
49 gr_feedforward_agc_cc::~gr_feedforward_agc_cc()
54 mag_squared(gr_complex x)
56 return x.real() * x.real() + x.imag() * x.imag();
59 // approximate sqrt(x^2 + y^2)
61 envelope(gr_complex x)
63 float r_abs = std::fabs(x.real());
64 float i_abs = std::fabs(x.imag());
67 return r_abs + 0.4 * i_abs;
69 return i_abs + 0.4 * r_abs;
73 gr_feedforward_agc_cc::work(int noutput_items,
74 gr_vector_const_void_star &input_items,
75 gr_vector_void_star &output_items)
77 const gr_complex *in = (const gr_complex *) input_items[0];
78 gr_complex *out = (gr_complex *) output_items[0];
79 int nsamples = d_nsamples;
82 for (int i = 0; i < noutput_items; i++){
83 //float max_env = 1e-12; // avoid divide by zero
84 float max_env = 1e-4; // avoid divide by zero, indirectly set max gain
85 for (int j = 0; j < nsamples; j++)
86 max_env = std::max(max_env, envelope(in[i+j]));
87 gain = d_reference / max_env;
88 out[i] = gain * in[i];