/* -*- c++ -*- */ /** * Copyright 2021 * Pablo Bertrand * Felipe Carrau * Victoria Severi * * Instituto de Ingeniería Eléctrica, Facultad de Ingeniería, * Universidad de la República, Uruguay. * * This 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. * * This software 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 this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. * * @file frame_drop_impl.cc * * gr-tempest * * @date September 19, 2021 * @author Pablo Bertrand * @author Felipe Carrau * @author Victoria Severi */ /********************************************************** * Include statements **********************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "frame_drop_impl.h" #include #include #include namespace gr { namespace tempest { frame_drop::sptr frame_drop::make(int Htotal, int Vtotal, int correct_sampling, float max_deviation, float update_proba, double actual_samp_rate) { return gnuradio::get_initial_sptr (new frame_drop_impl(Htotal, Vtotal, correct_sampling, max_deviation, update_proba, actual_samp_rate)); } /********************************************************** * Function bodies **********************************************************/ /* * The private constructor */ frame_drop_impl::frame_drop_impl(int Htotal, int Vtotal, int correct_sampling, float max_deviation, float update_proba, double actual_samp_rate) : gr::block("frame_drop", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(gr_complex))), d_inter(gr::filter::mmse_fir_interpolator_cc()), d_dist(update_proba), d_gen(std::random_device{}()) { set_relative_rate(1); //Counters d_sample_counter = 0; d_display_counter = 0; d_frames_counter = 0; //Fixed values d_discarded_amount_per_frame = 15; d_proba_of_updating = update_proba; d_max_deviation = max_deviation; d_alpha_samp_inc = 1e-1; d_last_freq = 0; d_samp_phase = 0; d_alpha_corr = 1e-6; d_start_frame_drop = 0; d_Htotal = Htotal; d_Vtotal = Vtotal; d_required_for_interpolation = d_Htotal*d_Vtotal; d_max_deviation_px = (int)std::ceil(d_Htotal*d_max_deviation); set_history(d_Vtotal*(d_Htotal+d_max_deviation_px)+1); d_peak_line_index = 0; d_samp_inc_rem = 0; d_new_interpolation_ratio_rem = 0; d_next_update = 0; // PMT port message_port_register_in(pmt::mp("ratio")); // PMT handler set_msg_handler(pmt::mp("ratio"),[this](const pmt::pmt_t& msg) {frame_drop_impl::set_ratio_msg(msg); }); } //--------------------------------------------------------- /* * Our virtual destructor. */ frame_drop_impl::~frame_drop_impl() { } //--------------------------------------------------------- void frame_drop_impl::forecast (int noutput_items, gr_vector_int &ninput_items_required) { int ninputs = ninput_items_required.size (); for (int i = 0; i < ninputs; i++) { ninput_items_required[i] = (int)ceil((noutput_items + 1) * (2+d_samp_inc_rem)) + d_inter.ntaps() ; } } //--------------------------------------------------------- void frame_drop_impl::set_ratio_msg(pmt::pmt_t msg){ if(pmt::is_pair(msg)) { pmt::pmt_t key = pmt::car(msg); pmt::pmt_t val = pmt::cdr(msg); if(pmt::eq(key, pmt::string_to_symbol("ratio"))) { if(pmt::is_number(val)) { d_new_interpolation_ratio_rem = (double)pmt::to_double(val); printf("Frame dropper: interpolation ratio received = %f \n", d_new_interpolation_ratio_rem); } } } } //--------------------------------------------------------- void frame_drop_impl::get_required_samples(int size) { uint32_t ii = 0, incr; int oo = 0; double s, f; //d_samp_inc_rem = (1-d_alpha_samp_inc)*d_samp_inc_rem + d_alpha_samp_inc*d_new_interpolation_ratio_rem; while(oo < size) { s = d_samp_phase + d_samp_inc_rem + 1; f = floor(s); incr = (uint32_t)f; d_samp_phase = s - f; ii += incr; oo++; } d_required_for_interpolation = ii; } //--------------------------------------------------------- int frame_drop_impl::general_work (int noutput_items, gr_vector_int &ninput_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 consumed = 0, out_amount = 0, aux; d_samp_inc_rem = (1-d_alpha_samp_inc)*d_samp_inc_rem + d_alpha_samp_inc*d_new_interpolation_ratio_rem; for (int i=0; i