/* -*- c++ -*- */ /* * Copyright 2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * * SPDX-License-Identifier: GPL-3.0-or-later * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ofdm_sync_sc_cfb_impl.h" #include <gnuradio/io_signature.h> #include <gnuradio/blocks/complex_to_arg.h> #include <gnuradio/blocks/complex_to_mag_squared.h> #include <gnuradio/blocks/conjugate_cc.h> #include <gnuradio/blocks/delay.h> #include <gnuradio/blocks/divide.h> #include <gnuradio/blocks/multiply.h> #include <gnuradio/blocks/sample_and_hold.h> #include <gnuradio/filter/fir_filter_blk.h> namespace gr { namespace digital { ofdm_sync_sc_cfb::sptr ofdm_sync_sc_cfb::make(int fft_len, int cp_len, bool use_even_carriers, float threshold) { return gnuradio::make_block_sptr<ofdm_sync_sc_cfb_impl>( fft_len, cp_len, use_even_carriers, threshold); } ofdm_sync_sc_cfb_impl::ofdm_sync_sc_cfb_impl(int fft_len, int cp_len, bool use_even_carriers, float threshold) : hier_block2("ofdm_sync_sc_cfb", io_signature::make(1, 1, sizeof(gr_complex)), #ifndef SYNC_ADD_DEBUG_OUTPUT io_signature::make2(2, 2, sizeof(float), sizeof(unsigned char))) #else io_signature::make3( 3, 3, sizeof(float), sizeof(unsigned char), sizeof(float))) #endif { std::vector<float> ma_taps(fft_len / 2, 1.0); gr::blocks::delay::sptr delay( gr::blocks::delay::make(sizeof(gr_complex), fft_len / 2)); gr::blocks::conjugate_cc::sptr delay_conjugate(gr::blocks::conjugate_cc::make()); gr::blocks::multiply_cc::sptr delay_corr(gr::blocks::multiply_cc::make()); gr::filter::fir_filter_ccf::sptr delay_ma(gr::filter::fir_filter_ccf::make( 1, std::vector<float>(fft_len / 2, use_even_carriers ? 1.0 : -1.0))); gr::blocks::complex_to_mag_squared::sptr delay_magsquare( gr::blocks::complex_to_mag_squared::make()); gr::blocks::divide_ff::sptr delay_normalize(gr::blocks::divide_ff::make()); gr::blocks::complex_to_mag_squared::sptr normalizer_magsquare( gr::blocks::complex_to_mag_squared::make()); gr::filter::fir_filter_fff::sptr normalizer_ma( gr::filter::fir_filter_fff::make(1, std::vector<float>(fft_len, 0.5))); gr::blocks::multiply_ff::sptr normalizer_square(gr::blocks::multiply_ff::make()); gr::blocks::complex_to_arg::sptr peak_to_angle(gr::blocks::complex_to_arg::make()); gr::blocks::sample_and_hold_ff::sptr sample_and_hold( gr::blocks::sample_and_hold_ff::make()); gr::blocks::plateau_detector_fb::sptr plateau_detector( gr::blocks::plateau_detector_fb::make(cp_len, threshold)); // store plateau detector for use in callback setting threshold d_plateau_detector = plateau_detector; // Delay Path connect(self(), 0, delay, 0); connect(delay, 0, delay_conjugate, 0); connect(delay_conjugate, 0, delay_corr, 1); connect(self(), 0, delay_corr, 0); connect(delay_corr, 0, delay_ma, 0); connect(delay_ma, 0, delay_magsquare, 0); connect(delay_magsquare, 0, delay_normalize, 0); // Energy Path connect(self(), 0, normalizer_magsquare, 0); connect(normalizer_magsquare, 0, normalizer_ma, 0); connect(normalizer_ma, 0, normalizer_square, 0); connect(normalizer_ma, 0, normalizer_square, 1); connect(normalizer_square, 0, delay_normalize, 1); // Fine frequency estimate (output 0) connect(delay_ma, 0, peak_to_angle, 0); connect(peak_to_angle, 0, sample_and_hold, 0); connect(sample_and_hold, 0, self(), 0); // Peak detect (output 1) connect(delay_normalize, 0, plateau_detector, 0); connect(plateau_detector, 0, sample_and_hold, 1); connect(plateau_detector, 0, self(), 1); #ifdef SYNC_ADD_DEBUG_OUTPUT // Debugging: timing metric (output 2) connect(delay_normalize, 0, self(), 2); #endif } ofdm_sync_sc_cfb_impl::~ofdm_sync_sc_cfb_impl() {} void ofdm_sync_sc_cfb_impl::set_threshold(float threshold) { d_plateau_detector->set_threshold(threshold); } float ofdm_sync_sc_cfb_impl::threshold() const { return d_plateau_detector->threshold(); } } /* namespace digital */ } /* namespace gr */