diff options
author | Tom Rondeau <trondeau@vt.edu> | 2012-08-17 22:31:02 -0400 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2012-08-17 22:31:02 -0400 |
commit | 5a92a70e6e4c9dd3a92055a772e01a9dee2df255 (patch) | |
tree | 40411983e1b189dae5cc189a0a734476df4c9170 /gr-digital | |
parent | 76a6f912706313fdc256b09aa17eeaf275e1fbc4 (diff) |
digital: converted OFDM blocks to new style.
Diffstat (limited to 'gr-digital')
37 files changed, 2096 insertions, 2024 deletions
diff --git a/gr-digital/include/digital/CMakeLists.txt b/gr-digital/include/digital/CMakeLists.txt index d22f5ad372..d8e17546ed 100644 --- a/gr-digital/include/digital/CMakeLists.txt +++ b/gr-digital/include/digital/CMakeLists.txt @@ -106,12 +106,12 @@ install(FILES metric_type.h mpsk_receiver_cc.h mpsk_snr_est_cc.h -# ofdm_cyclic_prefixer.h -# ofdm_frame_acquisition.h -# ofdm_frame_sink.h -# ofdm_insert_preamble.h -# ofdm_mapper_bcv.h -# ofdm_sampler.h + ofdm_cyclic_prefixer.h + ofdm_frame_acquisition.h + ofdm_frame_sink.h + ofdm_insert_preamble.h + ofdm_mapper_bcv.h + ofdm_sampler.h packet_sink.h pfb_clock_sync_ccf.h pfb_clock_sync_fff.h diff --git a/gr-digital/include/digital/ofdm_cyclic_prefixer.h b/gr-digital/include/digital/ofdm_cyclic_prefixer.h new file mode 100644 index 0000000000..142afc620d --- /dev/null +++ b/gr-digital/include/digital/ofdm_cyclic_prefixer.h @@ -0,0 +1,50 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004-2006,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H +#define INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H + +#include <digital/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace digital { + + /*! + * \brief adds a cyclic prefix vector to an input size long ofdm + * symbol(vector) and converts vector to a stream output_size + * long. + * \ingroup ofdm_blk + */ + class DIGITAL_API ofdm_cyclic_prefixer : virtual public gr_sync_interpolator + { + public: + // gr::digital::ofdm_cyclic_prefixer::sptr + typedef boost::shared_ptr<ofdm_cyclic_prefixer> sptr; + + static sptr make(size_t input_size, size_t output_size); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H */ diff --git a/gr-digital/include/digital/ofdm_frame_acquisition.h b/gr-digital/include/digital/ofdm_frame_acquisition.h new file mode 100644 index 0000000000..a255aa1801 --- /dev/null +++ b/gr-digital/include/digital/ofdm_frame_acquisition.h @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_H +#define INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_H + +#include <digital/api.h> +#include <gr_block.h> +#include <vector> + +namespace gr { + namespace digital { + + /*! + * \brief take a vector of complex constellation points in from an + * FFT and performs a correlation and equalization. + * \ingroup demodulation_blk + * \ingroup ofdm_blk + * + * This block takes the output of an FFT of a received OFDM symbol + * and finds the start of a frame based on two known symbols. It + * also looks at the surrounding bins in the FFT output for the + * correlation in case there is a large frequency shift in the + * data. This block assumes that the fine frequency shift has + * already been corrected and that the samples fall in the middle + * of one FFT bin. + * + * It then uses one of those known symbols to estimate the channel + * response over all subcarriers and does a simple 1-tap + * equalization on all subcarriers. This corrects for the phase + * and amplitude distortion caused by the channel. + */ + class DIGITAL_API ofdm_frame_acquisition : virtual public gr_block + { + public: + // gr::digital::ofdm_frame_acquisition::sptr + typedef boost::shared_ptr<ofdm_frame_acquisition> sptr; + + /*! + * Build an OFDM correlator and equalizer. + * + * \param occupied_carriers The number of subcarriers with data in the received symbol + * \param fft_length The size of the FFT vector (occupied_carriers + unused carriers) + * \param cplen The length of the cycle prefix + * \param known_symbol A vector of complex numbers representing a known symbol at the + * start of a frame (usually a BPSK PN sequence) + * \param max_fft_shift_len Set's the maximum distance you can look between bins for correlation + */ + static sptr make(unsigned int occupied_carriers, unsigned int fft_length, + unsigned int cplen, + const std::vector<gr_complex> &known_symbol, + unsigned int max_fft_shift_len); + + /*! + * \brief Return an estimate of the SNR of the channel + */ + virtual float snr() = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_H */ diff --git a/gr-digital/include/digital/ofdm_frame_sink.h b/gr-digital/include/digital/ofdm_frame_sink.h new file mode 100644 index 0000000000..64590ca980 --- /dev/null +++ b/gr-digital/include/digital/ofdm_frame_sink.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_FRAME_SINK_H +#define INCLUDED_DIGITAL_OFDM_FRAME_SINK_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <gr_msg_queue.h> + +namespace gr { + namespace digital { + + /*! + * \brief Takes an OFDM symbol in, demaps it into bits of 0's and + * 1's, packs them into packets, and sends to to a message queue + * sink. + * \ingroup sink_blk + * \ingroup ofdm_blk + * + * NOTE: The mod input parameter simply chooses a pre-defined + * demapper/slicer. Eventually, we want to be able to pass in a + * reference to an object to do the demapping and slicing for a + * given modulation type. + */ + class DIGITAL_API ofdm_frame_sink : virtual public gr_sync_block + { + public: + // gr::digital::ofdm_frame_sink::sptr + typedef boost::shared_ptr<ofdm_frame_sink> sptr; + + static sptr make(const std::vector<gr_complex> &sym_position, + const std::vector<unsigned char> &sym_value_out, + gr_msg_queue_sptr target_queue, + unsigned int occupied_tones, + float phase_gain, float freq_gain); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_OFDM_FRAME_SINK_H */ diff --git a/gr-digital/include/digital/ofdm_insert_preamble.h b/gr-digital/include/digital/ofdm_insert_preamble.h new file mode 100644 index 0000000000..05b760ded8 --- /dev/null +++ b/gr-digital/include/digital/ofdm_insert_preamble.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_H +#define INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_H + +#include <digital/api.h> +#include <gr_block.h> +#include <vector> + +namespace gr { + namespace digital { + + /*! + * \brief insert "pre-modulated" preamble symbols before each payload. + * \ingroup sync_blk + * \ingroup ofdm_blk + * + * <pre> + * input 1: stream of vectors of gr_complex [fft_length] + * These are the modulated symbols of the payload. + * + * input 2: stream of char. The LSB indicates whether the corresponding + * symbol on input 1 is the first symbol of the payload or not. + * It's a 1 if the corresponding symbol is the first symbol, + * otherwise 0. + * + * N.B., this implies that there must be at least 1 symbol in the payload. + * + * + * output 1: stream of vectors of gr_complex [fft_length] + * These include the preamble symbols and the payload symbols. + * + * output 2: stream of char. The LSB indicates whether the corresponding + * symbol on input 1 is the first symbol of a packet (i.e., the + * first symbol of the preamble.) It's a 1 if the corresponding + * symbol is the first symbol, otherwise 0. + * </pre> + * + * \param fft_length length of each symbol in samples. + * \param preamble vector of symbols that represent the pre-modulated preamble. + */ + class DIGITAL_API ofdm_insert_preamble : virtual public gr_block + { + public: + // gr::digital::ofdm_insert_preamble::sptr + typedef boost::shared_ptr<ofdm_insert_preamble> sptr; + + static sptr make(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble); + + virtual void enter_preamble() = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_H */ diff --git a/gr-digital/include/digital/ofdm_mapper_bcv.h b/gr-digital/include/digital/ofdm_mapper_bcv.h new file mode 100644 index 0000000000..eff2d79930 --- /dev/null +++ b/gr-digital/include/digital/ofdm_mapper_bcv.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_MAPPER_BCV_H +#define INCLUDED_DIGITAL_OFDM_MAPPER_BCV_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <gr_msg_queue.h> + +namespace gr { + namespace digital { + + /*! + * \brief take a stream of bytes in and map to a vector of complex + * constellation points suitable for IFFT input to be used in an + * ofdm modulator. Abstract class must be subclassed with + * specific mapping. + * \ingroup modulation_blk + * \ingroup ofdm_blk + */ + class DIGITAL_API ofdm_mapper_bcv : virtual public gr_sync_block + { + public: + // gr::digital::ofdm_mapper_bcv::sptr + typedef boost::shared_ptr<ofdm_mapper_bcv> sptr; + + static sptr make(const std::vector<gr_complex> &constellation, + unsigned msgq_limit, + unsigned occupied_carriers, + unsigned int fft_length); + + virtual gr_msg_queue_sptr msgq() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_MAPPER_BCV_H */ diff --git a/gr-digital/swig/digital_ofdm_cyclic_prefixer.i b/gr-digital/include/digital/ofdm_sampler.h index 56d1629a8a..4d6099a22c 100644 --- a/gr-digital/swig/digital_ofdm_cyclic_prefixer.i +++ b/gr-digital/include/digital/ofdm_sampler.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009,2011 Free Software Foundation, Inc. + * Copyright 2007,2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,15 +20,31 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(digital,ofdm_cyclic_prefixer) +#ifndef INCLUDED_DIGITAL_OFDM_SAMPLER_H +#define INCLUDED_DIGITAL_OFDM_SAMPLER_H -digital_ofdm_cyclic_prefixer_sptr -digital_make_ofdm_cyclic_prefixer (size_t input_size, size_t output_size); +#include <digital/api.h> +#include <gr_sync_block.h> -class digital_ofdm_cyclic_prefixer : public gr_sync_interpolator -{ - protected: - digital_ofdm_cyclic_prefixer (size_t input_size, size_t output_size); +namespace gr { + namespace digital { + + /*! + * \brief does the rest of the OFDM stuff + * \ingroup ofdm_blk + */ + class DIGITAL_API ofdm_sampler : virtual public gr_block + { + public: + // gr::digital::ofdm_sampler::sptr + typedef boost::shared_ptr<ofdm_sampler> sptr; - public: -}; + static sptr make(unsigned int fft_length, + unsigned int symbol_length, + unsigned int timeout); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_SAMPLER_H */ diff --git a/gr-digital/include/digital_ofdm_cyclic_prefixer.h b/gr-digital/include/digital_ofdm_cyclic_prefixer.h deleted file mode 100644 index 1b9682bb35..0000000000 --- a/gr-digital/include/digital_ofdm_cyclic_prefixer.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004-2006,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H -#define INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H - -#include <digital_api.h> -#include <gr_sync_interpolator.h> -#include <stdio.h> - -class digital_ofdm_cyclic_prefixer; -typedef boost::shared_ptr<digital_ofdm_cyclic_prefixer> digital_ofdm_cyclic_prefixer_sptr; - -DIGITAL_API digital_ofdm_cyclic_prefixer_sptr -digital_make_ofdm_cyclic_prefixer (size_t input_size, size_t output_size); - - -/*! - * \brief adds a cyclic prefix vector to an input size long ofdm - * symbol(vector) and converts vector to a stream output_size long. - * \ingroup ofdm_blk - */ -class DIGITAL_API digital_ofdm_cyclic_prefixer : public gr_sync_interpolator -{ - friend DIGITAL_API digital_ofdm_cyclic_prefixer_sptr - digital_make_ofdm_cyclic_prefixer (size_t input_size, size_t output_size); - - protected: - digital_ofdm_cyclic_prefixer (size_t input_size, size_t output_size); - - public: - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - private: - size_t d_input_size; - size_t d_output_size; -}; - -#endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H */ diff --git a/gr-digital/include/digital_ofdm_frame_acquisition.h b/gr-digital/include/digital_ofdm_frame_acquisition.h deleted file mode 100644 index 9c2f602334..0000000000 --- a/gr-digital/include/digital_ofdm_frame_acquisition.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_H -#define INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_H - -#include <digital_api.h> -#include <gr_block.h> -#include <vector> - -class digital_ofdm_frame_acquisition; -typedef boost::shared_ptr<digital_ofdm_frame_acquisition> digital_ofdm_frame_acquisition_sptr; - -digital_ofdm_frame_acquisition_sptr -DIGITAL_API digital_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int fft_length, - unsigned int cplen, - const std::vector<gr_complex> &known_symbol, - unsigned int max_fft_shift_len=10); - -/*! - * \brief take a vector of complex constellation points in from an FFT - * and performs a correlation and equalization. - * \ingroup demodulation_blk - * \ingroup ofdm_blk - * - * This block takes the output of an FFT of a received OFDM symbol and finds the - * start of a frame based on two known symbols. It also looks at the surrounding - * bins in the FFT output for the correlation in case there is a large frequency - * shift in the data. This block assumes that the fine frequency shift has already - * been corrected and that the samples fall in the middle of one FFT bin. - * - * It then uses one of those known - * symbols to estimate the channel response over all subcarriers and does a simple - * 1-tap equalization on all subcarriers. This corrects for the phase and amplitude - * distortion caused by the channel. - */ - -class DIGITAL_API digital_ofdm_frame_acquisition : public gr_block -{ - /*! - * \brief Build an OFDM correlator and equalizer. - * \param occupied_carriers The number of subcarriers with data in the received symbol - * \param fft_length The size of the FFT vector (occupied_carriers + unused carriers) - * \param cplen The length of the cycle prefix - * \param known_symbol A vector of complex numbers representing a known symbol at the - * start of a frame (usually a BPSK PN sequence) - * \param max_fft_shift_len Set's the maximum distance you can look between bins for correlation - */ - friend DIGITAL_API digital_ofdm_frame_acquisition_sptr - digital_make_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int fft_length, - unsigned int cplen, - const std::vector<gr_complex> &known_symbol, - unsigned int max_fft_shift_len); - -protected: - digital_ofdm_frame_acquisition (unsigned int occupied_carriers, unsigned int fft_length, - unsigned int cplen, - const std::vector<gr_complex> &known_symbol, - unsigned int max_fft_shift_len); - - private: - unsigned char slicer(gr_complex x); - void correlate(const gr_complex *symbol, int zeros_on_left); - void calculate_equalizer(const gr_complex *symbol, int zeros_on_left); - gr_complex coarse_freq_comp(int freq_delta, int count); - - unsigned int d_occupied_carriers; // !< \brief number of subcarriers with data - unsigned int d_fft_length; // !< \brief length of FFT vector - unsigned int d_cplen; // !< \brief length of cyclic prefix in samples - unsigned int d_freq_shift_len; // !< \brief number of surrounding bins to look at for correlation - std::vector<gr_complex> d_known_symbol; // !< \brief known symbols at start of frame - std::vector<float> d_known_phase_diff; // !< \brief factor used in correlation from known symbol - std::vector<float> d_symbol_phase_diff; // !< \brief factor used in correlation from received symbol - std::vector<gr_complex> d_hestimate; // !< channel estimate - int d_coarse_freq; // !< \brief search distance in number of bins - unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction - float d_snr_est; // !< an estimation of the signal to noise ratio - - gr_complex *d_phase_lut; // !< look-up table for coarse frequency compensation - - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - - public: - /*! - * \brief Return an estimate of the SNR of the channel - */ - float snr() { return d_snr_est; } - - ~digital_ofdm_frame_acquisition(void); - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - - -#endif diff --git a/gr-digital/include/digital_ofdm_frame_sink.h b/gr-digital/include/digital_ofdm_frame_sink.h deleted file mode 100644 index 5785d4be7b..0000000000 --- a/gr-digital/include/digital_ofdm_frame_sink.h +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_FRAME_SINK_H -#define INCLUDED_DIGITAL_OFDM_FRAME_SINK_H - -#include <digital_api.h> -#include <gr_sync_block.h> -#include <gr_msg_queue.h> - -class digital_ofdm_frame_sink; -typedef boost::shared_ptr<digital_ofdm_frame_sink> digital_ofdm_frame_sink_sptr; - -DIGITAL_API digital_ofdm_frame_sink_sptr -digital_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out, - gr_msg_queue_sptr target_queue, unsigned int occupied_tones, - float phase_gain=0.25, float freq_gain=0.25*0.25/4.0); - -/*! - * \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs - * them into packets, and sends to to a message queue sink. - * \ingroup sink_blk - * \ingroup ofdm_blk - * - * NOTE: The mod input parameter simply chooses a pre-defined demapper/slicer. Eventually, - * we want to be able to pass in a reference to an object to do the demapping and slicing - * for a given modulation type. - */ -class DIGITAL_API digital_ofdm_frame_sink : public gr_sync_block -{ - friend DIGITAL_API digital_ofdm_frame_sink_sptr - digital_make_ofdm_frame_sink (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out, - gr_msg_queue_sptr target_queue, unsigned int occupied_tones, - float phase_gain, float freq_gain); - - private: - enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER}; - - static const int MAX_PKT_LEN = 4096; - static const int HEADERBYTELEN = 4; - - gr_msg_queue_sptr d_target_queue; // where to send the packet when received - state_t d_state; - unsigned int d_header; // header bits - int d_headerbytelen_cnt; // how many so far - - unsigned char *d_bytes_out; // hold the current bytes produced by the demapper - - unsigned int d_occupied_carriers; - unsigned int d_byte_offset; - unsigned int d_partial_byte; - - unsigned char d_packet[MAX_PKT_LEN]; // assembled payload - int d_packetlen; // length of packet - int d_packet_whitener_offset; // offset into whitener string to use - int d_packetlen_cnt; // how many so far - - gr_complex * d_derotated_output; // Pointer to output stream to send deroated symbols out - - std::vector<gr_complex> d_sym_position; - std::vector<unsigned char> d_sym_value_out; - std::vector<gr_complex> d_dfe; - unsigned int d_nbits; - - unsigned char d_resid; - unsigned int d_nresid; - float d_phase; - float d_freq; - float d_phase_gain; - float d_freq_gain; - float d_eq_gain; - - std::vector<int> d_subcarrier_map; - - protected: - digital_ofdm_frame_sink(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out, - gr_msg_queue_sptr target_queue, unsigned int occupied_tones, - float phase_gain, float freq_gain); - - void enter_search(); - void enter_have_sync(); - void enter_have_header(); - - bool header_ok() - { - // confirm that two copies of header info are identical - return ((d_header >> 16) ^ (d_header & 0xffff)) == 0; - } - - unsigned char slicer(const gr_complex x); - unsigned int demapper(const gr_complex *in, - unsigned char *out); - - bool set_sym_value_out(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); - - public: - ~digital_ofdm_frame_sink(); - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif /* INCLUDED_GR_OFDM_FRAME_SINK_H */ diff --git a/gr-digital/include/digital_ofdm_insert_preamble.h b/gr-digital/include/digital_ofdm_insert_preamble.h deleted file mode 100644 index fa44558add..0000000000 --- a/gr-digital/include/digital_ofdm_insert_preamble.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_H -#define INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_H - -#include <digital_api.h> -#include <gr_block.h> -#include <vector> - -class digital_ofdm_insert_preamble; -typedef boost::shared_ptr<digital_ofdm_insert_preamble> digital_ofdm_insert_preamble_sptr; - -DIGITAL_API digital_ofdm_insert_preamble_sptr -digital_make_ofdm_insert_preamble(int fft_length, - const std::vector<std::vector<gr_complex> > &preamble); - -/*! - * \brief insert "pre-modulated" preamble symbols before each payload. - * \ingroup sync_blk - * \ingroup ofdm_blk - * - * <pre> - * input 1: stream of vectors of gr_complex [fft_length] - * These are the modulated symbols of the payload. - * - * input 2: stream of char. The LSB indicates whether the corresponding - * symbol on input 1 is the first symbol of the payload or not. - * It's a 1 if the corresponding symbol is the first symbol, - * otherwise 0. - * - * N.B., this implies that there must be at least 1 symbol in the payload. - * - * - * output 1: stream of vectors of gr_complex [fft_length] - * These include the preamble symbols and the payload symbols. - * - * output 2: stream of char. The LSB indicates whether the corresponding - * symbol on input 1 is the first symbol of a packet (i.e., the - * first symbol of the preamble.) It's a 1 if the corresponding - * symbol is the first symbol, otherwise 0. - * </pre> - * - * \param fft_length length of each symbol in samples. - * \param preamble vector of symbols that represent the pre-modulated preamble. - */ - -class DIGITAL_API digital_ofdm_insert_preamble : public gr_block -{ - friend DIGITAL_API digital_ofdm_insert_preamble_sptr - digital_make_ofdm_insert_preamble(int fft_length, - const std::vector<std::vector<gr_complex> > &preamble); - -protected: - digital_ofdm_insert_preamble(int fft_length, - const std::vector<std::vector<gr_complex> > &preamble); - -private: - enum state_t { - ST_IDLE, - ST_PREAMBLE, - ST_FIRST_PAYLOAD, - ST_PAYLOAD - }; - - int d_fft_length; - const std::vector<std::vector<gr_complex> > d_preamble; - state_t d_state; - int d_nsymbols_output; - int d_pending_flag; - - void enter_idle(); - void enter_first_payload(); - void enter_payload(); - - -public: - ~digital_ofdm_insert_preamble(); - void enter_preamble(); - - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - -}; - -#endif /* INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_H */ diff --git a/gr-digital/include/digital_ofdm_mapper_bcv.h b/gr-digital/include/digital_ofdm_mapper_bcv.h deleted file mode 100644 index daed1eab29..0000000000 --- a/gr-digital/include/digital_ofdm_mapper_bcv.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_MAPPER_BCV_H -#define INCLUDED_DIGITAL_OFDM_MAPPER_BCV_H - -#include <digital_api.h> -#include <gr_sync_block.h> -#include <gr_message.h> -#include <gr_msg_queue.h> - -class digital_ofdm_mapper_bcv; -typedef boost::shared_ptr<digital_ofdm_mapper_bcv> digital_ofdm_mapper_bcv_sptr; - -DIGITAL_API digital_ofdm_mapper_bcv_sptr -digital_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned msgq_limit, - unsigned occupied_carriers, unsigned int fft_length); - -/*! - * \brief take a stream of bytes in and map to a vector of complex - * constellation points suitable for IFFT input to be used in an ofdm - * modulator. Abstract class must be subclassed with specific mapping. - * \ingroup modulation_blk - * \ingroup ofdm_blk - */ - -class DIGITAL_API digital_ofdm_mapper_bcv : public gr_sync_block -{ - friend DIGITAL_API digital_ofdm_mapper_bcv_sptr - digital_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned msgq_limit, - unsigned occupied_carriers, unsigned int fft_length); -protected: - digital_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned msgq_limit, - unsigned occupied_carriers, unsigned int fft_length); - - private: - std::vector<gr_complex> d_constellation; - gr_msg_queue_sptr d_msgq; - gr_message_sptr d_msg; - unsigned d_msg_offset; - bool d_eof; - - unsigned int d_occupied_carriers; - unsigned int d_fft_length; - unsigned int d_bit_offset; - int d_pending_flag; - - unsigned long d_nbits; - unsigned char d_msgbytes; - - unsigned char d_resid; - unsigned int d_nresid; - - std::vector<int> d_subcarrier_map; - - int randsym(); - - public: - ~digital_ofdm_mapper_bcv(void); - - gr_msg_queue_sptr msgq() const { return d_msgq; } - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - -}; - -#endif diff --git a/gr-digital/include/digital_ofdm_sampler.h b/gr-digital/include/digital_ofdm_sampler.h deleted file mode 100644 index 9c54e4e776..0000000000 --- a/gr-digital/include/digital_ofdm_sampler.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_DIGITAL_OFDM_SAMPLER_H -#define INCLUDED_DIGITAL_OFDM_SAMPLER_H - -#include <digital_api.h> -#include <gr_sync_block.h> - -class digital_ofdm_sampler; -typedef boost::shared_ptr<digital_ofdm_sampler> digital_ofdm_sampler_sptr; - -DIGITAL_API digital_ofdm_sampler_sptr digital_make_ofdm_sampler (unsigned int fft_length, - unsigned int symbol_length, - unsigned int timeout=1000); - -/*! - * \brief does the rest of the OFDM stuff - * \ingroup ofdm_blk - */ -class DIGITAL_API digital_ofdm_sampler : public gr_block -{ - friend DIGITAL_API digital_ofdm_sampler_sptr digital_make_ofdm_sampler (unsigned int fft_length, - unsigned int symbol_length, - unsigned int timeout); - - digital_ofdm_sampler (unsigned int fft_length, - unsigned int symbol_length, - unsigned int timeout); - - private: - enum state_t {STATE_NO_SIG, STATE_PREAMBLE, STATE_FRAME}; - - state_t d_state; - unsigned int d_timeout_max; - unsigned int d_timeout; - unsigned int d_fft_length; - unsigned int d_symbol_length; - - public: - void forecast (int noutput_items, gr_vector_int &ninput_items_required); - - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif diff --git a/gr-digital/lib/CMakeLists.txt b/gr-digital/lib/CMakeLists.txt index 58ff70ef89..c95f78000d 100644 --- a/gr-digital/lib/CMakeLists.txt +++ b/gr-digital/lib/CMakeLists.txt @@ -131,12 +131,12 @@ list(APPEND digital_sources map_bb_impl.cc mpsk_receiver_cc_impl.cc mpsk_snr_est_cc_impl.cc - #ofdm_cyclic_prefixer_impl.cc - #ofdm_frame_acquisition_impl.cc - #ofdm_frame_sink_impl.cc - #ofdm_insert_preamble_impl.cc - #ofdm_mapper_bcv_impl.cc - #ofdm_sampler_impl.cc + ofdm_cyclic_prefixer_impl.cc + ofdm_frame_acquisition_impl.cc + ofdm_frame_sink_impl.cc + ofdm_insert_preamble_impl.cc + ofdm_mapper_bcv_impl.cc + ofdm_sampler_impl.cc packet_sink_impl.cc pfb_clock_sync_ccf_impl.cc pfb_clock_sync_fff_impl.cc diff --git a/gr-digital/lib/digital_ofdm_cyclic_prefixer.cc b/gr-digital/lib/digital_ofdm_cyclic_prefixer.cc deleted file mode 100644 index 192af2591d..0000000000 --- a/gr-digital/lib/digital_ofdm_cyclic_prefixer.cc +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2006,2010,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <digital_ofdm_cyclic_prefixer.h> -#include <gr_io_signature.h> - -digital_ofdm_cyclic_prefixer_sptr -digital_make_ofdm_cyclic_prefixer (size_t input_size, size_t output_size) -{ - return gnuradio::get_initial_sptr(new digital_ofdm_cyclic_prefixer (input_size, - output_size)); -} - -digital_ofdm_cyclic_prefixer::digital_ofdm_cyclic_prefixer (size_t input_size, - size_t output_size) - : gr_sync_interpolator ("ofdm_cyclic_prefixer", - gr_make_io_signature (1, 1, input_size*sizeof(gr_complex)), - gr_make_io_signature (1, 1, sizeof(gr_complex)), - output_size), - d_input_size(input_size), - d_output_size(output_size) - -{ -} - -int -digital_ofdm_cyclic_prefixer::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex *in = (gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - size_t cp_size = d_output_size - d_input_size; - unsigned int i=0, j=0; - - j = cp_size; - for(i=0; i < d_input_size; i++,j++) { - out[j] = in[i]; - } - - j = d_input_size - cp_size; - for(i=0; i < cp_size; i++, j++) { - out[i] = in[j]; - } - - return d_output_size; -} diff --git a/gr-digital/lib/digital_ofdm_frame_acquisition.cc b/gr-digital/lib/digital_ofdm_frame_acquisition.cc deleted file mode 100644 index 93b58aeca5..0000000000 --- a/gr-digital/lib/digital_ofdm_frame_acquisition.cc +++ /dev/null @@ -1,210 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006-2008,2010,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <digital_ofdm_frame_acquisition.h> -#include <gr_io_signature.h> -#include <gr_expj.h> -#include <gr_math.h> -#include <cstdio> - -#define VERBOSE 0 -#define M_TWOPI (2*M_PI) -#define MAX_NUM_SYMBOLS 1000 - -digital_ofdm_frame_acquisition_sptr -digital_make_ofdm_frame_acquisition (unsigned int occupied_carriers, - unsigned int fft_length, - unsigned int cplen, - const std::vector<gr_complex> &known_symbol, - unsigned int max_fft_shift_len) -{ - return gnuradio::get_initial_sptr(new digital_ofdm_frame_acquisition (occupied_carriers, fft_length, cplen, - known_symbol, max_fft_shift_len)); -} - -digital_ofdm_frame_acquisition::digital_ofdm_frame_acquisition (unsigned occupied_carriers, - unsigned int fft_length, - unsigned int cplen, - const std::vector<gr_complex> &known_symbol, - unsigned int max_fft_shift_len) - : gr_block ("ofdm_frame_acquisition", - gr_make_io_signature2 (2, 2, sizeof(gr_complex)*fft_length, sizeof(char)*fft_length), - gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char))), - d_occupied_carriers(occupied_carriers), - d_fft_length(fft_length), - d_cplen(cplen), - d_freq_shift_len(max_fft_shift_len), - d_known_symbol(known_symbol), - d_coarse_freq(0), - d_phase_count(0) -{ - d_symbol_phase_diff.resize(d_fft_length); - d_known_phase_diff.resize(d_occupied_carriers); - d_hestimate.resize(d_occupied_carriers); - - unsigned int i = 0, j = 0; - - std::fill(d_known_phase_diff.begin(), d_known_phase_diff.end(), 0); - for(i = 0; i < d_known_symbol.size()-2; i+=2) { - d_known_phase_diff[i] = norm(d_known_symbol[i] - d_known_symbol[i+2]); - } - - d_phase_lut = new gr_complex[(2*d_freq_shift_len+1) * MAX_NUM_SYMBOLS]; - for(i = 0; i <= 2*d_freq_shift_len; i++) { - for(j = 0; j < MAX_NUM_SYMBOLS; j++) { - d_phase_lut[j + i*MAX_NUM_SYMBOLS] = gr_expj(-M_TWOPI*d_cplen/d_fft_length*(i-d_freq_shift_len)*j); - } - } -} - -digital_ofdm_frame_acquisition::~digital_ofdm_frame_acquisition(void) -{ - delete [] d_phase_lut; -} - -void -digital_ofdm_frame_acquisition::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = 1; -} - -gr_complex -digital_ofdm_frame_acquisition::coarse_freq_comp(int freq_delta, int symbol_count) -{ - // return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count), - // sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count)); - - return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count); - - //return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count]; -} - -void -digital_ofdm_frame_acquisition::correlate(const gr_complex *symbol, int zeros_on_left) -{ - unsigned int i,j; - - std::fill(d_symbol_phase_diff.begin(), d_symbol_phase_diff.end(), 0); - for(i = 0; i < d_fft_length-2; i++) { - d_symbol_phase_diff[i] = norm(symbol[i] - symbol[i+2]); - } - - // sweep through all possible/allowed frequency offsets and select the best - int index = 0; - float max = 0, sum=0; - for(i = zeros_on_left - d_freq_shift_len; i < zeros_on_left + d_freq_shift_len; i++) { - sum = 0; - for(j = 0; j < d_occupied_carriers; j++) { - sum += (d_known_phase_diff[j] * d_symbol_phase_diff[i+j]); - } - if(sum > max) { - max = sum; - index = i; - } - } - - // set the coarse frequency offset relative to the edge of the occupied tones - d_coarse_freq = index - zeros_on_left; -} - -void -digital_ofdm_frame_acquisition::calculate_equalizer(const gr_complex *symbol, int zeros_on_left) -{ - unsigned int i=0; - - // Set first tap of equalizer - d_hestimate[0] = d_known_symbol[0] / - (coarse_freq_comp(d_coarse_freq,1)*symbol[zeros_on_left+d_coarse_freq]); - - // set every even tap based on known symbol - // linearly interpolate between set carriers to set zero-filled carriers - // FIXME: is this the best way to set this? - for(i = 2; i < d_occupied_carriers; i+=2) { - d_hestimate[i] = d_known_symbol[i] / - (coarse_freq_comp(d_coarse_freq,1)*(symbol[i+zeros_on_left+d_coarse_freq])); - d_hestimate[i-1] = (d_hestimate[i] + d_hestimate[i-2]) / gr_complex(2.0, 0.0); - } - - // with even number of carriers; last equalizer tap is wrong - if(!(d_occupied_carriers & 1)) { - d_hestimate[d_occupied_carriers-1] = d_hestimate[d_occupied_carriers-2]; - } - - if(VERBOSE) { - fprintf(stderr, "Equalizer setting:\n"); - for(i = 0; i < d_occupied_carriers; i++) { - gr_complex sym = coarse_freq_comp(d_coarse_freq,1)*symbol[i+zeros_on_left+d_coarse_freq]; - gr_complex output = sym * d_hestimate[i]; - fprintf(stderr, "sym: %+.4f + j%+.4f ks: %+.4f + j%+.4f eq: %+.4f + j%+.4f ==> %+.4f + j%+.4f\n", - sym .real(), sym.imag(), - d_known_symbol[i].real(), d_known_symbol[i].imag(), - d_hestimate[i].real(), d_hestimate[i].imag(), - output.real(), output.imag()); - } - fprintf(stderr, "\n"); - } -} - -int -digital_ofdm_frame_acquisition::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 *symbol = (const gr_complex *)input_items[0]; - const char *signal_in = (const char *)input_items[1]; - - gr_complex *out = (gr_complex *) output_items[0]; - char *signal_out = (char *) output_items[1]; - - int unoccupied_carriers = d_fft_length - d_occupied_carriers; - int zeros_on_left = (int)ceil(unoccupied_carriers/2.0); - - if(signal_in[0]) { - d_phase_count = 1; - correlate(symbol, zeros_on_left); - calculate_equalizer(symbol, zeros_on_left); - signal_out[0] = 1; - } - else { - signal_out[0] = 0; - } - - for(unsigned int i = 0; i < d_occupied_carriers; i++) { - out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count) - *symbol[i+zeros_on_left+d_coarse_freq]; - } - - d_phase_count++; - if(d_phase_count == MAX_NUM_SYMBOLS) { - d_phase_count = 1; - } - - consume_each(1); - return 1; -} diff --git a/gr-digital/lib/digital_ofdm_frame_sink.cc b/gr-digital/lib/digital_ofdm_frame_sink.cc deleted file mode 100644 index f8fb1bbb1d..0000000000 --- a/gr-digital/lib/digital_ofdm_frame_sink.cc +++ /dev/null @@ -1,405 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008,2010,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <digital_ofdm_frame_sink.h> -#include <gr_io_signature.h> -#include <gr_expj.h> -#include <gr_math.h> -#include <math.h> -#include <cstdio> -#include <stdexcept> -#include <iostream> -#include <string.h> - -#define VERBOSE 0 - -inline void -digital_ofdm_frame_sink::enter_search() -{ - if (VERBOSE) - fprintf(stderr, "@ enter_search\n"); - - d_state = STATE_SYNC_SEARCH; - -} - -inline void -digital_ofdm_frame_sink::enter_have_sync() -{ - if (VERBOSE) - fprintf(stderr, "@ enter_have_sync\n"); - - d_state = STATE_HAVE_SYNC; - - // clear state of demapper - d_byte_offset = 0; - d_partial_byte = 0; - - d_header = 0; - d_headerbytelen_cnt = 0; - - // Resetting PLL - d_freq = 0.0; - d_phase = 0.0; - fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); -} - -inline void -digital_ofdm_frame_sink::enter_have_header() -{ - d_state = STATE_HAVE_HEADER; - - // header consists of two 16-bit shorts in network byte order - // payload length is lower 12 bits - // whitener offset is upper 4 bits - d_packetlen = (d_header >> 16) & 0x0fff; - d_packet_whitener_offset = (d_header >> 28) & 0x000f; - d_packetlen_cnt = 0; - - if (VERBOSE) - fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", - d_packetlen, d_packet_whitener_offset); -} - - -unsigned char digital_ofdm_frame_sink::slicer(const gr_complex x) -{ - unsigned int table_size = d_sym_value_out.size(); - unsigned int min_index = 0; - float min_euclid_dist = norm(x - d_sym_position[0]); - float euclid_dist = 0; - - for (unsigned int j = 1; j < table_size; j++){ - euclid_dist = norm(x - d_sym_position[j]); - if (euclid_dist < min_euclid_dist){ - min_euclid_dist = euclid_dist; - min_index = j; - } - } - return d_sym_value_out[min_index]; -} - -unsigned int digital_ofdm_frame_sink::demapper(const gr_complex *in, - unsigned char *out) -{ - unsigned int i=0, bytes_produced=0; - gr_complex carrier; - - carrier=gr_expj(d_phase); - - gr_complex accum_error = 0.0; - //while(i < d_occupied_carriers) { - while(i < d_subcarrier_map.size()) { - if(d_nresid > 0) { - d_partial_byte |= d_resid; - d_byte_offset += d_nresid; - d_nresid = 0; - d_resid = 0; - } - - //while((d_byte_offset < 8) && (i < d_occupied_carriers)) { - while((d_byte_offset < 8) && (i < d_subcarrier_map.size())) { - //gr_complex sigrot = in[i]*carrier*d_dfe[i]; - gr_complex sigrot = in[d_subcarrier_map[i]]*carrier*d_dfe[i]; - - if(d_derotated_output != NULL){ - d_derotated_output[i] = sigrot; - } - - unsigned char bits = slicer(sigrot); - - gr_complex closest_sym = d_sym_position[bits]; - - accum_error += sigrot * conj(closest_sym); - - // FIX THE FOLLOWING STATEMENT - if (norm(sigrot)> 0.001) d_dfe[i] += d_eq_gain*(closest_sym/sigrot-d_dfe[i]); - - i++; - - if((8 - d_byte_offset) >= d_nbits) { - d_partial_byte |= bits << (d_byte_offset); - d_byte_offset += d_nbits; - } - else { - d_nresid = d_nbits-(8-d_byte_offset); - int mask = ((1<<(8-d_byte_offset))-1); - d_partial_byte |= (bits & mask) << d_byte_offset; - d_resid = bits >> (8-d_byte_offset); - d_byte_offset += (d_nbits - d_nresid); - } - //printf("demod symbol: %.4f + j%.4f bits: %x partial_byte: %x byte_offset: %d resid: %x nresid: %d\n", - // in[i-1].real(), in[i-1].imag(), bits, d_partial_byte, d_byte_offset, d_resid, d_nresid); - } - - if(d_byte_offset == 8) { - //printf("demod byte: %x \n\n", d_partial_byte); - out[bytes_produced++] = d_partial_byte; - d_byte_offset = 0; - d_partial_byte = 0; - } - } - //std::cerr << "accum_error " << accum_error << std::endl; - - float angle = arg(accum_error); - - d_freq = d_freq - d_freq_gain*angle; - d_phase = d_phase + d_freq - d_phase_gain*angle; - if (d_phase >= 2*M_PI) d_phase -= 2*M_PI; - if (d_phase <0) d_phase += 2*M_PI; - - //if(VERBOSE) - // std::cerr << angle << "\t" << d_freq << "\t" << d_phase << "\t" << std::endl; - - return bytes_produced; -} - - -digital_ofdm_frame_sink_sptr -digital_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out, - gr_msg_queue_sptr target_queue, unsigned int occupied_carriers, - float phase_gain, float freq_gain) -{ - return gnuradio::get_initial_sptr(new digital_ofdm_frame_sink(sym_position, sym_value_out, - target_queue, occupied_carriers, - phase_gain, freq_gain)); -} - - -digital_ofdm_frame_sink::digital_ofdm_frame_sink(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out, - gr_msg_queue_sptr target_queue, unsigned int occupied_carriers, - float phase_gain, float freq_gain) - : gr_sync_block ("ofdm_frame_sink", - gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)), - gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers)), - d_target_queue(target_queue), d_occupied_carriers(occupied_carriers), - d_byte_offset(0), d_partial_byte(0), - d_resid(0), d_nresid(0),d_phase(0),d_freq(0),d_phase_gain(phase_gain),d_freq_gain(freq_gain), - d_eq_gain(0.05) -{ - std::string carriers = "FE7F"; - - // A bit hacky to fill out carriers to occupied_carriers length - int diff = (d_occupied_carriers - 4*carriers.length()); - while(diff > 7) { - carriers.insert(0, "f"); - carriers.insert(carriers.length(), "f"); - diff -= 8; - } - - // if there's extras left to be processed - // divide remaining to put on either side of current map - // all of this is done to stick with the concept of a carrier map string that - // can be later passed by the user, even though it'd be cleaner to just do this - // on the carrier map itself - int diff_left=0; - int diff_right=0; - - // dictionary to convert from integers to ascii hex representation - char abc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - if(diff > 0) { - char c[2] = {0,0}; - - diff_left = (int)ceil((float)diff/2.0f); // number of carriers to put on the left side - c[0] = abc[(1 << diff_left) - 1]; // convert to bits and move to ASCI integer - carriers.insert(0, c); - - diff_right = diff - diff_left; // number of carriers to put on the right side - c[0] = abc[0xF^((1 << diff_right) - 1)]; // convert to bits and move to ASCI integer - carriers.insert(carriers.length(), c); - } - - // It seemed like such a good idea at the time... - // because we are only dealing with the occupied_carriers - // at this point, the diff_left in the following compensates - // for any offset from the 0th carrier introduced - unsigned int i,j,k; - for(i = 0; i < (d_occupied_carriers/4)+diff_left; i++) { - char c = carriers[i]; - for(j = 0; j < 4; j++) { - k = (strtol(&c, NULL, 16) >> (3-j)) & 0x1; - if(k) { - d_subcarrier_map.push_back(4*i + j - diff_left); - } - } - } - - // make sure we stay in the limit currently imposed by the occupied_carriers - if(d_subcarrier_map.size() > d_occupied_carriers) { - throw std::invalid_argument("digital_ofdm_mapper_bcv: subcarriers allocated exceeds size of occupied carriers"); - } - - d_bytes_out = new unsigned char[d_occupied_carriers]; - d_dfe.resize(occupied_carriers); - fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); - - set_sym_value_out(sym_position, sym_value_out); - - enter_search(); -} - -digital_ofdm_frame_sink::~digital_ofdm_frame_sink () -{ - delete [] d_bytes_out; -} - -bool -digital_ofdm_frame_sink::set_sym_value_out(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out) -{ - if (sym_position.size() != sym_value_out.size()) - return false; - - if (sym_position.size()<1) - return false; - - d_sym_position = sym_position; - d_sym_value_out = sym_value_out; - d_nbits = (unsigned long)ceil(log10(float(d_sym_value_out.size())) / log10(2.0)); - - return true; -} - - -int -digital_ofdm_frame_sink::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]; - const char *sig = (const char *) input_items[1]; - unsigned int j = 0; - unsigned int bytes=0; - - // If the output is connected, send it the derotated symbols - if(output_items.size() >= 1) - d_derotated_output = (gr_complex *)output_items[0]; - else - d_derotated_output = NULL; - - if (VERBOSE) - fprintf(stderr,">>> Entering state machine\n"); - - switch(d_state) { - - case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt - if (VERBOSE) - fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items); - - if (sig[0]) { // Found it, set up for header decode - enter_have_sync(); - } - break; - - case STATE_HAVE_SYNC: - // only demod after getting the preamble signal; otherwise, the - // equalizer taps will screw with the PLL performance - bytes = demapper(&in[0], d_bytes_out); - - if (VERBOSE) { - if(sig[0]) - printf("ERROR -- Found SYNC in HAVE_SYNC\n"); - fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", - d_headerbytelen_cnt, d_header); - } - - j = 0; - while(j < bytes) { - d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF); - j++; - - if (++d_headerbytelen_cnt == HEADERBYTELEN) { - - if (VERBOSE) - fprintf(stderr, "got header: 0x%08x\n", d_header); - - // we have a full header, check to see if it has been received properly - if (header_ok()){ - enter_have_header(); - - if (VERBOSE) - printf("\nPacket Length: %d\n", d_packetlen); - - while((j < bytes) && (d_packetlen_cnt < d_packetlen)) { - d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; - } - - if(d_packetlen_cnt == d_packetlen) { - gr_message_sptr msg = - gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen); - memcpy(msg->msg(), d_packet, d_packetlen_cnt); - d_target_queue->insert_tail(msg); // send it - msg.reset(); // free it up - - enter_search(); - } - } - else { - enter_search(); // bad header - } - } - } - break; - - case STATE_HAVE_HEADER: - bytes = demapper(&in[0], d_bytes_out); - - if (VERBOSE) { - if(sig[0]) - printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen); - fprintf(stderr,"Packet Build\n"); - } - - j = 0; - while(j < bytes) { - d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; - - if (d_packetlen_cnt == d_packetlen){ // packet is filled - // build a message - // NOTE: passing header field as arg1 is not scalable - gr_message_sptr msg = - gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt); - memcpy(msg->msg(), d_packet, d_packetlen_cnt); - - d_target_queue->insert_tail(msg); // send it - msg.reset(); // free it up - - enter_search(); - break; - } - } - break; - - default: - assert(0); - - } // switch - - return 1; -} diff --git a/gr-digital/lib/digital_ofdm_insert_preamble.cc b/gr-digital/lib/digital_ofdm_insert_preamble.cc deleted file mode 100644 index 72b9e82a82..0000000000 --- a/gr-digital/lib/digital_ofdm_insert_preamble.cc +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2010-2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <digital_ofdm_insert_preamble.h> -#include <gr_io_signature.h> -#include <stdexcept> -#include <iostream> -#include <string.h> - -digital_ofdm_insert_preamble_sptr -digital_make_ofdm_insert_preamble(int fft_length, - const std::vector<std::vector<gr_complex> > &preamble) -{ - return gnuradio::get_initial_sptr(new digital_ofdm_insert_preamble(fft_length, - preamble)); -} - -digital_ofdm_insert_preamble::digital_ofdm_insert_preamble - (int fft_length, - const std::vector<std::vector<gr_complex> > &preamble) - : gr_block("ofdm_insert_preamble", - gr_make_io_signature2(1, 2, - sizeof(gr_complex)*fft_length, - sizeof(char)), - gr_make_io_signature2(1, 2, - sizeof(gr_complex)*fft_length, - sizeof(char))), - d_fft_length(fft_length), - d_preamble(preamble), - d_state(ST_IDLE), - d_nsymbols_output(0), - d_pending_flag(0) -{ - // sanity check preamble symbols - for(size_t i = 0; i < d_preamble.size(); i++) { - if(d_preamble[i].size() != (size_t) d_fft_length) - throw std::invalid_argument("digital_ofdm_insert_preamble: invalid length for preamble symbol"); - } - - enter_idle(); -} - - -digital_ofdm_insert_preamble::~digital_ofdm_insert_preamble() -{ -} - -void digital_ofdm_insert_preamble::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - ninput_items_required[0] = noutput_items; -} - -int -digital_ofdm_insert_preamble::general_work(int noutput_items, - gr_vector_int &ninput_items_v, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - int ninput_items = ninput_items_v.size()==2?std::min(ninput_items_v[0], ninput_items_v[1]):ninput_items_v[0]; - const gr_complex *in_sym = (const gr_complex *) input_items[0]; - const unsigned char *in_flag = 0; - if (input_items.size() == 2) - in_flag = (const unsigned char *) input_items[1]; - - gr_complex *out_sym = (gr_complex *) output_items[0]; - unsigned char *out_flag = 0; - if (output_items.size() == 2) - out_flag = (unsigned char *) output_items[1]; - - - int no = 0; // number items output - int ni = 0; // number items read from input - - -#define write_out_flag() \ - do { if (out_flag) \ - out_flag[no] = d_pending_flag; \ - d_pending_flag = 0; \ - } while(0) - - - while (no < noutput_items && ni < ninput_items){ - switch(d_state){ - case ST_IDLE: - if (in_flag && in_flag[ni] & 0x1) // this is first symbol of new payload - enter_preamble(); - else - ni++; // eat one input symbol - break; - - case ST_PREAMBLE: - assert(!in_flag || in_flag[ni] & 0x1); - if (d_nsymbols_output >= (int) d_preamble.size()){ - // we've output all the preamble - enter_first_payload(); - } - else { - memcpy(&out_sym[no * d_fft_length], - &d_preamble[d_nsymbols_output][0], - d_fft_length*sizeof(gr_complex)); - - write_out_flag(); - no++; - d_nsymbols_output++; - } - break; - - case ST_FIRST_PAYLOAD: - // copy first payload symbol from input to output - memcpy(&out_sym[no * d_fft_length], - &in_sym[ni * d_fft_length], - d_fft_length * sizeof(gr_complex)); - - write_out_flag(); - no++; - ni++; - enter_payload(); - break; - - case ST_PAYLOAD: - if (in_flag && in_flag[ni] & 0x1){ // this is first symbol of a new payload - enter_preamble(); - break; - } - - // copy a symbol from input to output - memcpy(&out_sym[no * d_fft_length], - &in_sym[ni * d_fft_length], - d_fft_length * sizeof(gr_complex)); - - write_out_flag(); - no++; - ni++; - break; - - default: - std::cerr << "digital_ofdm_insert_preamble: (can't happen) invalid state, resetting\n"; - enter_idle(); - } - } - - consume_each(ni); - return no; -} - -void -digital_ofdm_insert_preamble::enter_idle() -{ - d_state = ST_IDLE; - d_nsymbols_output = 0; - d_pending_flag = 0; -} - -void -digital_ofdm_insert_preamble::enter_preamble() -{ - d_state = ST_PREAMBLE; - d_nsymbols_output = 0; - d_pending_flag = 1; -} - -void -digital_ofdm_insert_preamble::enter_first_payload() -{ - d_state = ST_FIRST_PAYLOAD; -} - -void -digital_ofdm_insert_preamble::enter_payload() -{ - d_state = ST_PAYLOAD; -} diff --git a/gr-digital/lib/digital_ofdm_mapper_bcv.cc b/gr-digital/lib/digital_ofdm_mapper_bcv.cc deleted file mode 100644 index cf3d08703a..0000000000 --- a/gr-digital/lib/digital_ofdm_mapper_bcv.cc +++ /dev/null @@ -1,241 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006-2008,2010,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <digital_ofdm_mapper_bcv.h> -#include <gr_io_signature.h> -#include <stdexcept> -#include <string.h> - -digital_ofdm_mapper_bcv_sptr -digital_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned int msgq_limit, - unsigned int occupied_carriers, unsigned int fft_length) -{ - return gnuradio::get_initial_sptr(new digital_ofdm_mapper_bcv (constellation, msgq_limit, - occupied_carriers, fft_length)); -} - -// Consumes 1 packet and produces as many OFDM symbols of fft_length to hold the full packet -digital_ofdm_mapper_bcv::digital_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned int msgq_limit, - unsigned int occupied_carriers, unsigned int fft_length) - : gr_sync_block ("ofdm_mapper_bcv", - gr_make_io_signature (0, 0, 0), - gr_make_io_signature2 (1, 2, sizeof(gr_complex)*fft_length, sizeof(char))), - d_constellation(constellation), - d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false), - d_occupied_carriers(occupied_carriers), - d_fft_length(fft_length), - d_bit_offset(0), - d_pending_flag(0), - d_resid(0), - d_nresid(0) -{ - if (!(d_occupied_carriers <= d_fft_length)) - throw std::invalid_argument("digital_ofdm_mapper_bcv: occupied carriers must be <= fft_length"); - - // this is not the final form of this solution since we still use the occupied_tones concept, - // which would get us into trouble if the number of carriers we seek is greater than the occupied carriers. - // Eventually, we will get rid of the occupied_carriers concept. - std::string carriers = "FE7F"; - - // A bit hacky to fill out carriers to occupied_carriers length - int diff = (d_occupied_carriers - 4*carriers.length()); - while(diff > 7) { - carriers.insert(0, "f"); - carriers.insert(carriers.length(), "f"); - diff -= 8; - } - - // if there's extras left to be processed - // divide remaining to put on either side of current map - // all of this is done to stick with the concept of a carrier map string that - // can be later passed by the user, even though it'd be cleaner to just do this - // on the carrier map itself - int diff_left=0; - int diff_right=0; - - // dictionary to convert from integers to ascii hex representation - char abc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - if(diff > 0) { - char c[2] = {0,0}; - - diff_left = (int)ceil((float)diff/2.0f); // number of carriers to put on the left side - c[0] = abc[(1 << diff_left) - 1]; // convert to bits and move to ASCI integer - carriers.insert(0, c); - - diff_right = diff - diff_left; // number of carriers to put on the right side - c[0] = abc[0xF^((1 << diff_right) - 1)]; // convert to bits and move to ASCI integer - carriers.insert(carriers.length(), c); - } - - // find out how many zeros to pad on the sides; the difference between the fft length and the subcarrier - // mapping size in chunks of four. This is the number to pack on the left and this number plus any - // residual nulls (if odd) will be packed on the right. - diff = (d_fft_length/4 - carriers.length())/2; - - unsigned int i,j,k; - for(i = 0; i < carriers.length(); i++) { - char c = carriers[i]; // get the current hex character from the string - for(j = 0; j < 4; j++) { // walk through all four bits - k = (strtol(&c, NULL, 16) >> (3-j)) & 0x1; // convert to int and extract next bit - if(k) { // if bit is a 1, - d_subcarrier_map.push_back(4*(i+diff) + j); // use this subcarrier - } - } - } - - // make sure we stay in the limit currently imposed by the occupied_carriers - if(d_subcarrier_map.size() > d_occupied_carriers) { - throw std::invalid_argument("digital_ofdm_mapper_bcv: subcarriers allocated exceeds size of occupied carriers"); - } - - d_nbits = (unsigned long)ceil(log10(float(d_constellation.size())) / log10(2.0)); -} - -digital_ofdm_mapper_bcv::~digital_ofdm_mapper_bcv(void) -{ -} - -int digital_ofdm_mapper_bcv::randsym() -{ - return (rand() % d_constellation.size()); -} - -int -digital_ofdm_mapper_bcv::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex *out = (gr_complex *)output_items[0]; - - unsigned int i=0; - - //printf("OFDM BPSK Mapper: ninput_items: %d noutput_items: %d\n", ninput_items[0], noutput_items); - - if(d_eof) { - return -1; - } - - if(!d_msg) { - d_msg = d_msgq->delete_head(); // block, waiting for a message - d_msg_offset = 0; - d_bit_offset = 0; - d_pending_flag = 1; // new packet, write start of packet flag - - if((d_msg->length() == 0) && (d_msg->type() == 1)) { - d_msg.reset(); - return -1; // We're done; no more messages coming. - } - } - - char *out_flag = 0; - if(output_items.size() == 2) - out_flag = (char *) output_items[1]; - - - // Build a single symbol: - // Initialize all bins to 0 to set unused carriers - memset(out, 0, d_fft_length*sizeof(gr_complex)); - - i = 0; - unsigned char bits = 0; - //while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) { - while((d_msg_offset < d_msg->length()) && (i < d_subcarrier_map.size())) { - - // need new data to process - if(d_bit_offset == 0) { - d_msgbytes = d_msg->msg()[d_msg_offset]; - //printf("mod message byte: %x\n", d_msgbytes); - } - - if(d_nresid > 0) { - // take the residual bits, fill out nbits with info from the new byte, and put them in the symbol - d_resid |= (((1 << d_nresid)-1) & d_msgbytes) << (d_nbits - d_nresid); - bits = d_resid; - - out[d_subcarrier_map[i]] = d_constellation[bits]; - i++; - - d_bit_offset += d_nresid; - d_nresid = 0; - d_resid = 0; - //printf("mod bit(r): %x resid: %x nresid: %d bit_offset: %d\n", - // bits, d_resid, d_nresid, d_bit_offset); - } - else { - if((8 - d_bit_offset) >= d_nbits) { // test to make sure we can fit nbits - // take the nbits number of bits at a time from the byte to add to the symbol - bits = ((1 << d_nbits)-1) & (d_msgbytes >> d_bit_offset); - d_bit_offset += d_nbits; - - out[d_subcarrier_map[i]] = d_constellation[bits]; - i++; - } - else { // if we can't fit nbits, store them for the next - // saves d_nresid bits of this message where d_nresid < d_nbits - unsigned int extra = 8-d_bit_offset; - d_resid = ((1 << extra)-1) & (d_msgbytes >> d_bit_offset); - d_bit_offset += extra; - d_nresid = d_nbits - extra; - } - - } - - if(d_bit_offset == 8) { - d_bit_offset = 0; - d_msg_offset++; - } - } - - // Ran out of data to put in symbol - if (d_msg_offset == d_msg->length()) { - if(d_nresid > 0) { - d_resid |= 0x00; - bits = d_resid; - d_nresid = 0; - d_resid = 0; - } - - //while(i < d_occupied_carriers) { // finish filling out the symbol - while(i < d_subcarrier_map.size()) { // finish filling out the symbol - out[d_subcarrier_map[i]] = d_constellation[randsym()]; - - i++; - } - - if (d_msg->type() == 1) // type == 1 sets EOF - d_eof = true; - d_msg.reset(); // finished packet, free message - assert(d_bit_offset == 0); - } - - if (out_flag) - out_flag[0] = d_pending_flag; - d_pending_flag = 0; - - return 1; // produced symbol -} diff --git a/gr-digital/lib/digital_ofdm_sampler.cc b/gr-digital/lib/digital_ofdm_sampler.cc deleted file mode 100644 index cab8c2ba93..0000000000 --- a/gr-digital/lib/digital_ofdm_sampler.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008,2010,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <digital_ofdm_sampler.h> -#include <gr_io_signature.h> -#include <gr_expj.h> -#include <cstdio> - -digital_ofdm_sampler_sptr -digital_make_ofdm_sampler (unsigned int fft_length, - unsigned int symbol_length, - unsigned int timeout) -{ - return gnuradio::get_initial_sptr(new digital_ofdm_sampler (fft_length, symbol_length, timeout)); -} - -digital_ofdm_sampler::digital_ofdm_sampler (unsigned int fft_length, - unsigned int symbol_length, - unsigned int timeout) - : gr_block ("ofdm_sampler", - gr_make_io_signature2 (2, 2, sizeof (gr_complex), sizeof(char)), - gr_make_io_signature2 (2, 2, sizeof (gr_complex)*fft_length, sizeof(char)*fft_length)), - d_state(STATE_NO_SIG), d_timeout_max(timeout), d_fft_length(fft_length), d_symbol_length(symbol_length) -{ - set_relative_rate(1.0/(double) fft_length); // buffer allocator hint -} - -void -digital_ofdm_sampler::forecast (int noutput_items, gr_vector_int &ninput_items_required) -{ - // FIXME do we need more - //int nreqd = (noutput_items-1) * d_symbol_length + d_fft_length; - int nreqd = d_symbol_length + d_fft_length; - unsigned ninputs = ninput_items_required.size (); - for (unsigned i = 0; i < ninputs; i++) - ninput_items_required[i] = nreqd; -} - - -int -digital_ofdm_sampler::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 *iptr = (const gr_complex *) input_items[0]; - const char *trigger = (const char *) input_items[1]; - - gr_complex *optr = (gr_complex *) output_items[0]; - char *outsig = (char *) output_items[1]; - - //FIXME: we only process a single OFDM symbol at a time; after the preamble, we can - // process a few at a time as long as we always look out for the next preamble. - - unsigned int index=d_fft_length; // start one fft length into the input so we can always look back this far - - outsig[0] = 0; // set output to no signal by default - - // Search for a preamble trigger signal during the next symbol length - while((d_state != STATE_PREAMBLE) && (index <= (d_symbol_length+d_fft_length))) { - if(trigger[index]) { - outsig[0] = 1; // tell the next block there is a preamble coming - d_state = STATE_PREAMBLE; - } - else - index++; - } - - unsigned int i, pos, ret; - switch(d_state) { - case(STATE_PREAMBLE): - // When we found a preamble trigger, get it and set the symbol boundary here - for(i = (index - d_fft_length + 1); i <= index; i++) { - *optr++ = iptr[i]; - } - - d_timeout = d_timeout_max; // tell the system to expect at least this many symbols for a frame - d_state = STATE_FRAME; - consume_each(index - d_fft_length + 1); // consume up to one fft_length away to keep the history - ret = 1; - break; - - case(STATE_FRAME): - // use this state when we have processed a preamble and are getting the rest of the frames - //FIXME: we could also have a power squelch system here to enter STATE_NO_SIG if no power is received - - // skip over fft length history and cyclic prefix - pos = d_symbol_length; // keeps track of where we are in the input buffer - while(pos < d_symbol_length + d_fft_length) { - *optr++ = iptr[pos++]; - } - - if(d_timeout-- == 0) { - printf("TIMEOUT\n"); - d_state = STATE_NO_SIG; - } - - consume_each(d_symbol_length); // jump up by 1 fft length and the cyclic prefix length - ret = 1; - break; - - case(STATE_NO_SIG): - default: - consume_each(index-d_fft_length); // consume everything we've gone through so far leaving the fft length history - ret = 0; - break; - } - - return ret; -} diff --git a/gr-digital/lib/ofdm_cyclic_prefixer_impl.cc b/gr-digital/lib/ofdm_cyclic_prefixer_impl.cc new file mode 100644 index 0000000000..67cfba615f --- /dev/null +++ b/gr-digital/lib/ofdm_cyclic_prefixer_impl.cc @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ofdm_cyclic_prefixer_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace digital { + + ofdm_cyclic_prefixer::sptr + ofdm_cyclic_prefixer::make(size_t input_size, size_t output_size) + { + return gnuradio::get_initial_sptr + (new ofdm_cyclic_prefixer_impl(input_size, output_size)); + } + + ofdm_cyclic_prefixer_impl::ofdm_cyclic_prefixer_impl(size_t input_size, + size_t output_size) + : gr_sync_interpolator("ofdm_cyclic_prefixer", + gr_make_io_signature(1, 1, input_size*sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex)), + output_size), + d_input_size(input_size), + d_output_size(output_size) + { + } + + ofdm_cyclic_prefixer_impl::~ofdm_cyclic_prefixer_impl() + { + } + + int + ofdm_cyclic_prefixer_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *in = (gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + size_t cp_size = d_output_size - d_input_size; + unsigned int i=0, j=0; + + j = cp_size; + for(i=0; i < d_input_size; i++,j++) { + out[j] = in[i]; + } + + j = d_input_size - cp_size; + for(i=0; i < cp_size; i++, j++) { + out[i] = in[j]; + } + + return d_output_size; + } + + } /* namespace digital */ +} /* namespace gr */ diff --git a/gr-digital/swig/digital_ofdm_insert_preamble.i b/gr-digital/lib/ofdm_cyclic_prefixer_impl.h index 0273c7fa75..20f0489d7c 100644 --- a/gr-digital/swig/digital_ofdm_insert_preamble.i +++ b/gr-digital/lib/ofdm_cyclic_prefixer_impl.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2011 Free Software Foundation, Inc. + * Copyright 2004-2006,2011,2012 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,18 +20,30 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(digital,ofdm_insert_preamble); +#ifndef INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_IMPL_H +#define INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_IMPL_H -digital_ofdm_insert_preamble_sptr -digital_make_ofdm_insert_preamble(int fft_length, - const std::vector<std::vector<gr_complex> > &preamble); +#include <digital/ofdm_cyclic_prefixer.h> +namespace gr { + namespace digital { + + class ofdm_cyclic_prefixer_impl : public ofdm_cyclic_prefixer + { + private: + size_t d_input_size; + size_t d_output_size; -class digital_ofdm_insert_preamble : public gr_block -{ - protected: - digital_ofdm_insert_preamble(int fft_length, - const std::vector<std::vector<gr_complex> > &preamble); - public: - void enter_preamble(); -}; + public: + ofdm_cyclic_prefixer_impl(size_t input_size, size_t output_size); + ~ofdm_cyclic_prefixer_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_IMPL_H */ diff --git a/gr-digital/lib/ofdm_frame_acquisition_impl.cc b/gr-digital/lib/ofdm_frame_acquisition_impl.cc new file mode 100644 index 0000000000..1f45338d8f --- /dev/null +++ b/gr-digital/lib/ofdm_frame_acquisition_impl.cc @@ -0,0 +1,217 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006-2008,2010,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ofdm_frame_acquisition_impl.h" +#include <gr_io_signature.h> +#include <gr_expj.h> +#include <gr_math.h> +#include <cstdio> + +namespace gr { + namespace digital { + +#define VERBOSE 0 +#define M_TWOPI (2*M_PI) +#define MAX_NUM_SYMBOLS 1000 + + ofdm_frame_acquisition::sptr + ofdm_frame_acquisition::make(unsigned int occupied_carriers, + unsigned int fft_length, + unsigned int cplen, + const std::vector<gr_complex> &known_symbol, + unsigned int max_fft_shift_len) + { + return gnuradio::get_initial_sptr + (new ofdm_frame_acquisition_impl(occupied_carriers, fft_length, cplen, + known_symbol, max_fft_shift_len)); + } + + ofdm_frame_acquisition_impl::ofdm_frame_acquisition_impl(unsigned occupied_carriers, + unsigned int fft_length, + unsigned int cplen, + const std::vector<gr_complex> &known_symbol, + unsigned int max_fft_shift_len) + : gr_block("ofdm_frame_acquisition", + gr_make_io_signature2(2, 2, sizeof(gr_complex)*fft_length, sizeof(char)*fft_length), + gr_make_io_signature2(2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char))), + d_occupied_carriers(occupied_carriers), + d_fft_length(fft_length), + d_cplen(cplen), + d_freq_shift_len(max_fft_shift_len), + d_known_symbol(known_symbol), + d_coarse_freq(0), + d_phase_count(0) + { + d_symbol_phase_diff.resize(d_fft_length); + d_known_phase_diff.resize(d_occupied_carriers); + d_hestimate.resize(d_occupied_carriers); + + unsigned int i = 0, j = 0; + + std::fill(d_known_phase_diff.begin(), d_known_phase_diff.end(), 0); + for(i = 0; i < d_known_symbol.size()-2; i+=2) { + d_known_phase_diff[i] = norm(d_known_symbol[i] - d_known_symbol[i+2]); + } + + d_phase_lut = new gr_complex[(2*d_freq_shift_len+1) * MAX_NUM_SYMBOLS]; + for(i = 0; i <= 2*d_freq_shift_len; i++) { + for(j = 0; j < MAX_NUM_SYMBOLS; j++) { + d_phase_lut[j + i*MAX_NUM_SYMBOLS] = gr_expj(-M_TWOPI*d_cplen/d_fft_length*(i-d_freq_shift_len)*j); + } + } + } + + ofdm_frame_acquisition_impl::~ofdm_frame_acquisition_impl() + { + delete [] d_phase_lut; + } + + void + ofdm_frame_acquisition_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) + { + unsigned ninputs = ninput_items_required.size(); + for(unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = 1; + } + + gr_complex + ofdm_frame_acquisition_impl::coarse_freq_comp(int freq_delta, int symbol_count) + { + // return gr_complex(cos(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count), + // sin(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count)); + + return gr_expj(-M_TWOPI*freq_delta*d_cplen/d_fft_length*symbol_count); + + //return d_phase_lut[MAX_NUM_SYMBOLS * (d_freq_shift_len + freq_delta) + symbol_count]; + } + + void + ofdm_frame_acquisition_impl::correlate(const gr_complex *symbol, int zeros_on_left) + { + unsigned int i,j; + + std::fill(d_symbol_phase_diff.begin(), d_symbol_phase_diff.end(), 0); + for(i = 0; i < d_fft_length-2; i++) { + d_symbol_phase_diff[i] = norm(symbol[i] - symbol[i+2]); + } + + // sweep through all possible/allowed frequency offsets and select the best + int index = 0; + float max = 0, sum=0; + for(i = zeros_on_left - d_freq_shift_len; i < zeros_on_left + d_freq_shift_len; i++) { + sum = 0; + for(j = 0; j < d_occupied_carriers; j++) { + sum += (d_known_phase_diff[j] * d_symbol_phase_diff[i+j]); + } + if(sum > max) { + max = sum; + index = i; + } + } + + // set the coarse frequency offset relative to the edge of the occupied tones + d_coarse_freq = index - zeros_on_left; + } + + void + ofdm_frame_acquisition_impl::calculate_equalizer(const gr_complex *symbol, int zeros_on_left) + { + unsigned int i=0; + + // Set first tap of equalizer + d_hestimate[0] = d_known_symbol[0] / + (coarse_freq_comp(d_coarse_freq,1)*symbol[zeros_on_left+d_coarse_freq]); + + // set every even tap based on known symbol + // linearly interpolate between set carriers to set zero-filled carriers + // FIXME: is this the best way to set this? + for(i = 2; i < d_occupied_carriers; i+=2) { + d_hestimate[i] = d_known_symbol[i] / + (coarse_freq_comp(d_coarse_freq,1)*(symbol[i+zeros_on_left+d_coarse_freq])); + d_hestimate[i-1] = (d_hestimate[i] + d_hestimate[i-2]) / gr_complex(2.0, 0.0); + } + + // with even number of carriers; last equalizer tap is wrong + if(!(d_occupied_carriers & 1)) { + d_hestimate[d_occupied_carriers-1] = d_hestimate[d_occupied_carriers-2]; + } + + if(VERBOSE) { + fprintf(stderr, "Equalizer setting:\n"); + for(i = 0; i < d_occupied_carriers; i++) { + gr_complex sym = coarse_freq_comp(d_coarse_freq,1)*symbol[i+zeros_on_left+d_coarse_freq]; + gr_complex output = sym * d_hestimate[i]; + fprintf(stderr, "sym: %+.4f + j%+.4f ks: %+.4f + j%+.4f eq: %+.4f + j%+.4f ==> %+.4f + j%+.4f\n", + sym .real(), sym.imag(), + d_known_symbol[i].real(), d_known_symbol[i].imag(), + d_hestimate[i].real(), d_hestimate[i].imag(), + output.real(), output.imag()); + } + fprintf(stderr, "\n"); + } + } + + int + ofdm_frame_acquisition_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 *symbol = (const gr_complex *)input_items[0]; + const char *signal_in = (const char *)input_items[1]; + + gr_complex *out = (gr_complex *) output_items[0]; + char *signal_out = (char *) output_items[1]; + + int unoccupied_carriers = d_fft_length - d_occupied_carriers; + int zeros_on_left = (int)ceil(unoccupied_carriers/2.0); + + if(signal_in[0]) { + d_phase_count = 1; + correlate(symbol, zeros_on_left); + calculate_equalizer(symbol, zeros_on_left); + signal_out[0] = 1; + } + else { + signal_out[0] = 0; + } + + for(unsigned int i = 0; i < d_occupied_carriers; i++) { + out[i] = d_hestimate[i]*coarse_freq_comp(d_coarse_freq,d_phase_count) + *symbol[i+zeros_on_left+d_coarse_freq]; + } + + d_phase_count++; + if(d_phase_count == MAX_NUM_SYMBOLS) { + d_phase_count = 1; + } + + consume_each(1); + return 1; + } + + } /* namespace digital */ +} /* namespace gr */ diff --git a/gr-digital/lib/ofdm_frame_acquisition_impl.h b/gr-digital/lib/ofdm_frame_acquisition_impl.h new file mode 100644 index 0000000000..c4e11404fd --- /dev/null +++ b/gr-digital/lib/ofdm_frame_acquisition_impl.h @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_IMPL_H +#define INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_IMPL_H + +#include <digital/ofdm_frame_acquisition.h> + +namespace gr { + namespace digital { + + class ofdm_frame_acquisition_impl : public ofdm_frame_acquisition + { + private: + unsigned char slicer(gr_complex x); + void correlate(const gr_complex *symbol, int zeros_on_left); + void calculate_equalizer(const gr_complex *symbol, int zeros_on_left); + gr_complex coarse_freq_comp(int freq_delta, int count); + + unsigned int d_occupied_carriers; // !< \brief number of subcarriers with data + unsigned int d_fft_length; // !< \brief length of FFT vector + unsigned int d_cplen; // !< \brief length of cyclic prefix in samples + unsigned int d_freq_shift_len; // !< \brief number of surrounding bins to look at for correlation + std::vector<gr_complex> d_known_symbol; // !< \brief known symbols at start of frame + std::vector<float> d_known_phase_diff; // !< \brief factor used in correlation from known symbol + std::vector<float> d_symbol_phase_diff; // !< \brief factor used in correlation from received symbol + std::vector<gr_complex> d_hestimate; // !< channel estimate + int d_coarse_freq; // !< \brief search distance in number of bins + unsigned int d_phase_count; // !< \brief accumulator for coarse freq correction + float d_snr_est; // !< an estimation of the signal to noise ratio + + gr_complex *d_phase_lut; // !< look-up table for coarse frequency compensation + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + public: + ofdm_frame_acquisition_impl(unsigned int occupied_carriers, unsigned int fft_length, + unsigned int cplen, + const std::vector<gr_complex> &known_symbol, + unsigned int max_fft_shift_len); + ~ofdm_frame_acquisition_impl(); + + /*! + * \brief Return an estimate of the SNR of the channel + */ + float snr() { return d_snr_est; } + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_FRAME_ACQUISITION_IMPL_H */ diff --git a/gr-digital/lib/ofdm_frame_sink_impl.cc b/gr-digital/lib/ofdm_frame_sink_impl.cc new file mode 100644 index 0000000000..71c287e21b --- /dev/null +++ b/gr-digital/lib/ofdm_frame_sink_impl.cc @@ -0,0 +1,412 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ofdm_frame_sink_impl.h" +#include <gr_io_signature.h> +#include <gr_expj.h> +#include <gr_math.h> +#include <cmath> +#include <cstdio> +#include <stdexcept> +#include <iostream> +#include <string> + +namespace gr { + namespace digital { + +#define VERBOSE 0 + + inline void + ofdm_frame_sink_impl::enter_search() + { + if(VERBOSE) + fprintf(stderr, "@ enter_search\n"); + + d_state = STATE_SYNC_SEARCH; + } + + inline void + ofdm_frame_sink_impl::enter_have_sync() + { + if(VERBOSE) + fprintf(stderr, "@ enter_have_sync\n"); + + d_state = STATE_HAVE_SYNC; + + // clear state of demapper + d_byte_offset = 0; + d_partial_byte = 0; + + d_header = 0; + d_headerbytelen_cnt = 0; + + // Resetting PLL + d_freq = 0.0; + d_phase = 0.0; + fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); + } + + inline void + ofdm_frame_sink_impl::enter_have_header() + { + d_state = STATE_HAVE_HEADER; + + // header consists of two 16-bit shorts in network byte order + // payload length is lower 12 bits + // whitener offset is upper 4 bits + d_packetlen = (d_header >> 16) & 0x0fff; + d_packet_whitener_offset = (d_header >> 28) & 0x000f; + d_packetlen_cnt = 0; + + if(VERBOSE) + fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", + d_packetlen, d_packet_whitener_offset); + } + + unsigned char + ofdm_frame_sink_impl::slicer(const gr_complex x) + { + unsigned int table_size = d_sym_value_out.size(); + unsigned int min_index = 0; + float min_euclid_dist = norm(x - d_sym_position[0]); + float euclid_dist = 0; + + for(unsigned int j = 1; j < table_size; j++){ + euclid_dist = norm(x - d_sym_position[j]); + if(euclid_dist < min_euclid_dist){ + min_euclid_dist = euclid_dist; + min_index = j; + } + } + return d_sym_value_out[min_index]; + } + + unsigned int ofdm_frame_sink_impl::demapper(const gr_complex *in, + unsigned char *out) + { + unsigned int i=0, bytes_produced=0; + gr_complex carrier; + + carrier = gr_expj(d_phase); + + gr_complex accum_error = 0.0; + //while(i < d_occupied_carriers) { + while(i < d_subcarrier_map.size()) { + if(d_nresid > 0) { + d_partial_byte |= d_resid; + d_byte_offset += d_nresid; + d_nresid = 0; + d_resid = 0; + } + + //while((d_byte_offset < 8) && (i < d_occupied_carriers)) { + while((d_byte_offset < 8) && (i < d_subcarrier_map.size())) { + //gr_complex sigrot = in[i]*carrier*d_dfe[i]; + gr_complex sigrot = in[d_subcarrier_map[i]]*carrier*d_dfe[i]; + + if(d_derotated_output != NULL){ + d_derotated_output[i] = sigrot; + } + + unsigned char bits = slicer(sigrot); + + gr_complex closest_sym = d_sym_position[bits]; + + accum_error += sigrot * conj(closest_sym); + + // FIX THE FOLLOWING STATEMENT + if(norm(sigrot)> 0.001) + d_dfe[i] += d_eq_gain*(closest_sym/sigrot-d_dfe[i]); + + i++; + + if((8 - d_byte_offset) >= d_nbits) { + d_partial_byte |= bits << (d_byte_offset); + d_byte_offset += d_nbits; + } + else { + d_nresid = d_nbits-(8-d_byte_offset); + int mask = ((1<<(8-d_byte_offset))-1); + d_partial_byte |= (bits & mask) << d_byte_offset; + d_resid = bits >> (8-d_byte_offset); + d_byte_offset += (d_nbits - d_nresid); + } + //printf("demod symbol: %.4f + j%.4f bits: %x partial_byte: %x byte_offset: %d resid: %x nresid: %d\n", + // in[i-1].real(), in[i-1].imag(), bits, d_partial_byte, d_byte_offset, d_resid, d_nresid); + } + + if(d_byte_offset == 8) { + //printf("demod byte: %x \n\n", d_partial_byte); + out[bytes_produced++] = d_partial_byte; + d_byte_offset = 0; + d_partial_byte = 0; + } + } + //std::cerr << "accum_error " << accum_error << std::endl; + + float angle = arg(accum_error); + + d_freq = d_freq - d_freq_gain*angle; + d_phase = d_phase + d_freq - d_phase_gain*angle; + if(d_phase >= 2*M_PI) + d_phase -= 2*M_PI; + if(d_phase <0) + d_phase += 2*M_PI; + + //if(VERBOSE) + // std::cerr << angle << "\t" << d_freq << "\t" << d_phase << "\t" << std::endl; + + return bytes_produced; + } + + + ofdm_frame_sink::sptr + ofdm_frame_sink::make(const std::vector<gr_complex> &sym_position, + const std::vector<unsigned char> &sym_value_out, + gr_msg_queue_sptr target_queue, + unsigned int occupied_carriers, + float phase_gain, float freq_gain) + { + return gnuradio::get_initial_sptr + (new ofdm_frame_sink_impl(sym_position, sym_value_out, + target_queue, occupied_carriers, + phase_gain, freq_gain)); + } + + ofdm_frame_sink_impl::ofdm_frame_sink_impl(const std::vector<gr_complex> &sym_position, + const std::vector<unsigned char> &sym_value_out, + gr_msg_queue_sptr target_queue, + unsigned int occupied_carriers, + float phase_gain, float freq_gain) + : gr_sync_block("ofdm_frame_sink", + gr_make_io_signature2(2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)), + gr_make_io_signature(1, 1, sizeof(gr_complex)*occupied_carriers)), + d_target_queue(target_queue), d_occupied_carriers(occupied_carriers), + d_byte_offset(0), d_partial_byte(0), + d_resid(0), d_nresid(0),d_phase(0),d_freq(0), + d_phase_gain(phase_gain),d_freq_gain(freq_gain), + d_eq_gain(0.05) + { + std::string carriers = "FE7F"; + + // A bit hacky to fill out carriers to occupied_carriers length + int diff = (d_occupied_carriers - 4*carriers.length()); + while(diff > 7) { + carriers.insert(0, "f"); + carriers.insert(carriers.length(), "f"); + diff -= 8; + } + + // if there's extras left to be processed + // divide remaining to put on either side of current map + // all of this is done to stick with the concept of a carrier map string that + // can be later passed by the user, even though it'd be cleaner to just do this + // on the carrier map itself + int diff_left=0; + int diff_right=0; + + // dictionary to convert from integers to ascii hex representation + char abc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + if(diff > 0) { + char c[2] = {0,0}; + + diff_left = (int)ceil((float)diff/2.0f); // number of carriers to put on the left side + c[0] = abc[(1 << diff_left) - 1]; // convert to bits and move to ASCI integer + carriers.insert(0, c); + + diff_right = diff - diff_left; // number of carriers to put on the right side + c[0] = abc[0xF^((1 << diff_right) - 1)]; // convert to bits and move to ASCI integer + carriers.insert(carriers.length(), c); + } + + // It seemed like such a good idea at the time... + // because we are only dealing with the occupied_carriers + // at this point, the diff_left in the following compensates + // for any offset from the 0th carrier introduced + unsigned int i,j,k; + for(i = 0; i < (d_occupied_carriers/4)+diff_left; i++) { + char c = carriers[i]; + for(j = 0; j < 4; j++) { + k = (strtol(&c, NULL, 16) >> (3-j)) & 0x1; + if(k) { + d_subcarrier_map.push_back(4*i + j - diff_left); + } + } + } + + // make sure we stay in the limit currently imposed by the occupied_carriers + if(d_subcarrier_map.size() > d_occupied_carriers) { + throw std::invalid_argument("ofdm_frame_sink_impl: subcarriers allocated exceeds size of occupied carriers"); + } + + d_bytes_out = new unsigned char[d_occupied_carriers]; + d_dfe.resize(occupied_carriers); + fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); + + set_sym_value_out(sym_position, sym_value_out); + + enter_search(); + } + + ofdm_frame_sink_impl::~ofdm_frame_sink_impl() + { + delete [] d_bytes_out; + } + + bool + ofdm_frame_sink_impl::set_sym_value_out(const std::vector<gr_complex> &sym_position, + const std::vector<unsigned char> &sym_value_out) + { + if(sym_position.size() != sym_value_out.size()) + return false; + + if(sym_position.size()<1) + return false; + + d_sym_position = sym_position; + d_sym_value_out = sym_value_out; + d_nbits = (unsigned long)ceil(log10(float(d_sym_value_out.size())) / log10(2.0)); + + return true; + } + + int + ofdm_frame_sink_impl::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]; + const char *sig = (const char*)input_items[1]; + unsigned int j = 0; + unsigned int bytes=0; + + // If the output is connected, send it the derotated symbols + if(output_items.size() >= 1) + d_derotated_output = (gr_complex *)output_items[0]; + else + d_derotated_output = NULL; + + if(VERBOSE) + fprintf(stderr,">>> Entering state machine\n"); + + switch(d_state) { + case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt + if(VERBOSE) + fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items); + + if(sig[0]) { // Found it, set up for header decode + enter_have_sync(); + } + break; + + case STATE_HAVE_SYNC: + // only demod after getting the preamble signal; otherwise, the + // equalizer taps will screw with the PLL performance + bytes = demapper(&in[0], d_bytes_out); + + if(VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_SYNC\n"); + fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", + d_headerbytelen_cnt, d_header); + } + + j = 0; + while(j < bytes) { + d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF); + j++; + + if(++d_headerbytelen_cnt == HEADERBYTELEN) { + if(VERBOSE) + fprintf(stderr, "got header: 0x%08x\n", d_header); + + // we have a full header, check to see if it has been received properly + if(header_ok()) { + enter_have_header(); + + if(VERBOSE) + printf("\nPacket Length: %d\n", d_packetlen); + + while((j < bytes) && (d_packetlen_cnt < d_packetlen)) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + } + + if(d_packetlen_cnt == d_packetlen) { + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + } + } + else { + enter_search(); // bad header + } + } + } + break; + + case STATE_HAVE_HEADER: + bytes = demapper(&in[0], d_bytes_out); + + if(VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen); + fprintf(stderr,"Packet Build\n"); + } + + j = 0; + while(j < bytes) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + + if (d_packetlen_cnt == d_packetlen){ // packet is filled + // build a message + // NOTE: passing header field as arg1 is not scalable + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + break; + } + } + break; + + default: + assert(0); + } // switch + + return 1; + } + + } /* namespace digital */ +} /* namespace gr */ diff --git a/gr-digital/lib/ofdm_frame_sink_impl.h b/gr-digital/lib/ofdm_frame_sink_impl.h new file mode 100644 index 0000000000..9414b38b33 --- /dev/null +++ b/gr-digital/lib/ofdm_frame_sink_impl.h @@ -0,0 +1,106 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_FRAME_SINK_IMPL_H +#define INCLUDED_DIGITAL_OFDM_FRAME_SINK_IMPL_H + +#include <digital/ofdm_frame_sink.h> + +namespace gr { + namespace digital { + + class ofdm_frame_sink_impl : public ofdm_frame_sink + { + private: + enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER}; + + static const int MAX_PKT_LEN = 4096; + static const int HEADERBYTELEN = 4; + + gr_msg_queue_sptr d_target_queue; // where to send the packet when received + state_t d_state; + unsigned int d_header; // header bits + int d_headerbytelen_cnt; // how many so far + + unsigned char *d_bytes_out; // hold the current bytes produced by the demapper + + unsigned int d_occupied_carriers; + unsigned int d_byte_offset; + unsigned int d_partial_byte; + + unsigned char d_packet[MAX_PKT_LEN]; // assembled payload + int d_packetlen; // length of packet + int d_packet_whitener_offset; // offset into whitener string to use + int d_packetlen_cnt; // how many so far + + gr_complex * d_derotated_output; // Pointer to output stream to send deroated symbols out + + std::vector<gr_complex> d_sym_position; + std::vector<unsigned char> d_sym_value_out; + std::vector<gr_complex> d_dfe; + unsigned int d_nbits; + + unsigned char d_resid; + unsigned int d_nresid; + float d_phase; + float d_freq; + float d_phase_gain; + float d_freq_gain; + float d_eq_gain; + + std::vector<int> d_subcarrier_map; + + protected: + void enter_search(); + void enter_have_sync(); + void enter_have_header(); + + bool header_ok() + { + // confirm that two copies of header info are identical + return ((d_header >> 16) ^ (d_header & 0xffff)) == 0; + } + + unsigned char slicer(const gr_complex x); + unsigned int demapper(const gr_complex *in, + unsigned char *out); + + bool set_sym_value_out(const std::vector<gr_complex> &sym_position, + const std::vector<unsigned char> &sym_value_out); + + public: + ofdm_frame_sink_impl(const std::vector<gr_complex> &sym_position, + const std::vector<unsigned char> &sym_value_out, + gr_msg_queue_sptr target_queue, + unsigned int occupied_tones, + float phase_gain, float freq_gain); + ~ofdm_frame_sink_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_OFDM_FRAME_SINK_IMPL_H */ diff --git a/gr-digital/lib/ofdm_insert_preamble_impl.cc b/gr-digital/lib/ofdm_insert_preamble_impl.cc new file mode 100644 index 0000000000..100e69e22c --- /dev/null +++ b/gr-digital/lib/ofdm_insert_preamble_impl.cc @@ -0,0 +1,201 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ofdm_insert_preamble_impl.h" +#include <gr_io_signature.h> +#include <stdexcept> +#include <iostream> +#include <string> + +namespace gr { + namespace digital { + + ofdm_insert_preamble::sptr + ofdm_insert_preamble::make(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble) + { + return gnuradio::get_initial_sptr + (new ofdm_insert_preamble_impl(fft_length, preamble)); + } + + ofdm_insert_preamble_impl::ofdm_insert_preamble_impl(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble) + : gr_block("ofdm_insert_preamble", + gr_make_io_signature2(1, 2, + sizeof(gr_complex)*fft_length, + sizeof(char)), + gr_make_io_signature2(1, 2, + sizeof(gr_complex)*fft_length, + sizeof(char))), + d_fft_length(fft_length), + d_state(ST_IDLE), + d_nsymbols_output(0), + d_pending_flag(0), + d_preamble(preamble) + { + // sanity check preamble symbols + for(size_t i = 0; i < d_preamble.size(); i++) { + if(d_preamble[i].size() != (size_t) d_fft_length) + throw std::invalid_argument("ofdm_insert_preamble_impl: invalid length for preamble symbol"); + } + + enter_idle(); + } + + + ofdm_insert_preamble_impl::~ofdm_insert_preamble_impl() + { + } + + void + ofdm_insert_preamble_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) + { + ninput_items_required[0] = noutput_items; + } + + int + ofdm_insert_preamble_impl::general_work(int noutput_items, + gr_vector_int &ninput_items_v, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + int ninput_items = ninput_items_v.size() == 2 ? + std::min(ninput_items_v[0], ninput_items_v[1]) : ninput_items_v[0]; + + const gr_complex *in_sym = (const gr_complex *)input_items[0]; + const unsigned char *in_flag = 0; + + if(input_items.size() == 2) + in_flag = (const unsigned char*)input_items[1]; + + gr_complex *out_sym = (gr_complex*)output_items[0]; + unsigned char *out_flag = 0; + if(output_items.size() == 2) + out_flag = (unsigned char*)output_items[1]; + + int no = 0; // number items output + int ni = 0; // number items read from input + +#define write_out_flag() \ + do { \ + if(out_flag) \ + out_flag[no] = d_pending_flag; \ + d_pending_flag = 0; \ + } while(0) + + while(no < noutput_items && ni < ninput_items) { + switch(d_state) { + case ST_IDLE: + if(in_flag && in_flag[ni] & 0x1) // this is first symbol of new payload + enter_preamble(); + else + ni++; // eat one input symbol + break; + + case ST_PREAMBLE: + assert(!in_flag || in_flag[ni] & 0x1); + if(d_nsymbols_output >= (int) d_preamble.size()) { + // we've output all the preamble + enter_first_payload(); + } + else { + memcpy(&out_sym[no * d_fft_length], + &d_preamble[d_nsymbols_output][0], + d_fft_length*sizeof(gr_complex)); + + write_out_flag(); + no++; + d_nsymbols_output++; + } + break; + + case ST_FIRST_PAYLOAD: + // copy first payload symbol from input to output + memcpy(&out_sym[no * d_fft_length], + &in_sym[ni * d_fft_length], + d_fft_length * sizeof(gr_complex)); + + write_out_flag(); + no++; + ni++; + enter_payload(); + break; + + case ST_PAYLOAD: + if(in_flag && in_flag[ni] & 0x1) { // this is first symbol of a new payload + enter_preamble(); + break; + } + + // copy a symbol from input to output + memcpy(&out_sym[no * d_fft_length], + &in_sym[ni * d_fft_length], + d_fft_length * sizeof(gr_complex)); + + write_out_flag(); + no++; + ni++; + break; + + default: + std::cerr << "ofdm_insert_preamble_impl: (can't happen) invalid state, resetting\n"; + enter_idle(); + } + } + + consume_each(ni); + return no; + } + + void + ofdm_insert_preamble_impl::enter_idle() + { + d_state = ST_IDLE; + d_nsymbols_output = 0; + d_pending_flag = 0; + } + + void + ofdm_insert_preamble_impl::enter_preamble() + { + d_state = ST_PREAMBLE; + d_nsymbols_output = 0; + d_pending_flag = 1; + } + + void + ofdm_insert_preamble_impl::enter_first_payload() + { + d_state = ST_FIRST_PAYLOAD; + } + + void + ofdm_insert_preamble_impl::enter_payload() + { + d_state = ST_PAYLOAD; + } + + } /* namespace digital */ +} /* namespace gr */ diff --git a/gr-digital/lib/ofdm_insert_preamble_impl.h b/gr-digital/lib/ofdm_insert_preamble_impl.h new file mode 100644 index 0000000000..cd47810daf --- /dev/null +++ b/gr-digital/lib/ofdm_insert_preamble_impl.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_IMPL_H +#define INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_IMPL_H + +#include <digital/ofdm_insert_preamble.h> + +namespace gr { + namespace digital { + + class ofdm_insert_preamble_impl : public ofdm_insert_preamble + { + private: + enum state_t { + ST_IDLE, + ST_PREAMBLE, + ST_FIRST_PAYLOAD, + ST_PAYLOAD + }; + + int d_fft_length; + state_t d_state; + int d_nsymbols_output; + int d_pending_flag; + const std::vector<std::vector<gr_complex> > d_preamble; + + void enter_idle(); + void enter_first_payload(); + void enter_payload(); + + public: + ofdm_insert_preamble_impl(int fft_length, + const std::vector<std::vector<gr_complex> > &preamble); + ~ofdm_insert_preamble_impl(); + + void enter_preamble(); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_INSERT_PREAMBLE_IMPL_H */ diff --git a/gr-digital/lib/ofdm_mapper_bcv_impl.cc b/gr-digital/lib/ofdm_mapper_bcv_impl.cc new file mode 100644 index 0000000000..5b5359d7b9 --- /dev/null +++ b/gr-digital/lib/ofdm_mapper_bcv_impl.cc @@ -0,0 +1,252 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006-2008,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ofdm_mapper_bcv_impl.h" +#include <gr_io_signature.h> +#include <stdexcept> +#include <string> + +namespace gr { + namespace digital { + + ofdm_mapper_bcv::sptr + ofdm_mapper_bcv::make(const std::vector<gr_complex> &constellation, + unsigned int msgq_limit, + unsigned int occupied_carriers, + unsigned int fft_length) + { + return gnuradio::get_initial_sptr + (new ofdm_mapper_bcv_impl(constellation, msgq_limit, + occupied_carriers, fft_length)); + } + + // Consumes 1 packet and produces as many OFDM symbols of + // fft_length to hold the full packet + ofdm_mapper_bcv_impl::ofdm_mapper_bcv_impl(const std::vector<gr_complex> &constellation, + unsigned int msgq_limit, + unsigned int occupied_carriers, + unsigned int fft_length) + : gr_sync_block("ofdm_mapper_bcv", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature2(1, 2, sizeof(gr_complex)*fft_length, sizeof(char))), + d_constellation(constellation), + d_msgq(gr_make_msg_queue(msgq_limit)), d_msg_offset(0), d_eof(false), + d_occupied_carriers(occupied_carriers), + d_fft_length(fft_length), + d_bit_offset(0), + d_pending_flag(0), + d_resid(0), + d_nresid(0) + { + if(!(d_occupied_carriers <= d_fft_length)) + throw std::invalid_argument("ofdm_mapper_bcv_impl: occupied carriers must be <= fft_length"); + + // this is not the final form of this solution since we still + // use the occupied_tones concept, which would get us into + // trouble if the number of carriers we seek is greater than the + // occupied carriers. + // Eventually, we will get rid of the occupied_carriers concept. + std::string carriers = "FE7F"; + + // A bit hacky to fill out carriers to occupied_carriers length + int diff = (d_occupied_carriers - 4*carriers.length()); + while(diff > 7) { + carriers.insert(0, "f"); + carriers.insert(carriers.length(), "f"); + diff -= 8; + } + + // if there's extras left to be processed divide remaining to + // put on either side of current map all of this is done to + // stick with the concept of a carrier map string that can be + // later passed by the user, even though it'd be cleaner to just + // do this on the carrier map itself + int diff_left=0; + int diff_right=0; + + // dictionary to convert from integers to ascii hex representation + char abc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + if(diff > 0) { + char c[2] = {0,0}; + + diff_left = (int)ceil((float)diff/2.0f); // number of carriers to put on the left side + c[0] = abc[(1 << diff_left) - 1]; // convert to bits and move to ASCI integer + carriers.insert(0, c); + + diff_right = diff - diff_left; // number of carriers to put on the right side + c[0] = abc[0xF^((1 << diff_right) - 1)]; // convert to bits and move to ASCI integer + carriers.insert(carriers.length(), c); + } + + // find out how many zeros to pad on the sides; the difference between the fft length and the subcarrier + // mapping size in chunks of four. This is the number to pack on the left and this number plus any + // residual nulls (if odd) will be packed on the right. + diff = (d_fft_length/4 - carriers.length())/2; + + unsigned int i,j,k; + for(i = 0; i < carriers.length(); i++) { + char c = carriers[i]; // get the current hex character from the string + for(j = 0; j < 4; j++) { // walk through all four bits + k = (strtol(&c, NULL, 16) >> (3-j)) & 0x1; // convert to int and extract next bit + if(k) { // if bit is a 1, + d_subcarrier_map.push_back(4*(i+diff) + j); // use this subcarrier + } + } + } + + // make sure we stay in the limit currently imposed by the occupied_carriers + if(d_subcarrier_map.size() > d_occupied_carriers) { + throw std::invalid_argument("ofdm_mapper_bcv_impl: subcarriers allocated exceeds size of occupied carriers"); + } + + d_nbits = (unsigned long)ceil(log10(float(d_constellation.size())) / log10(2.0)); + } + + ofdm_mapper_bcv_impl::~ofdm_mapper_bcv_impl() + { + } + + int ofdm_mapper_bcv_impl::randsym() + { + return (rand() % d_constellation.size()); + } + + int + ofdm_mapper_bcv_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *out = (gr_complex *)output_items[0]; + + unsigned int i=0; + + //printf("OFDM BPSK Mapper: ninput_items: %d noutput_items: %d\n", ninput_items[0], noutput_items); + + if(d_eof) { + return -1; + } + + if(!d_msg) { + d_msg = d_msgq->delete_head(); // block, waiting for a message + d_msg_offset = 0; + d_bit_offset = 0; + d_pending_flag = 1; // new packet, write start of packet flag + + if((d_msg->length() == 0) && (d_msg->type() == 1)) { + d_msg.reset(); + return -1; // We're done; no more messages coming. + } + } + + char *out_flag = 0; + if(output_items.size() == 2) + out_flag = (char *) output_items[1]; + + + // Build a single symbol: + // Initialize all bins to 0 to set unused carriers + memset(out, 0, d_fft_length*sizeof(gr_complex)); + + i = 0; + unsigned char bits = 0; + //while((d_msg_offset < d_msg->length()) && (i < d_occupied_carriers)) { + while((d_msg_offset < d_msg->length()) && (i < d_subcarrier_map.size())) { + + // need new data to process + if(d_bit_offset == 0) { + d_msgbytes = d_msg->msg()[d_msg_offset]; + //printf("mod message byte: %x\n", d_msgbytes); + } + + if(d_nresid > 0) { + // take the residual bits, fill out nbits with info from the new byte, and put them in the symbol + d_resid |= (((1 << d_nresid)-1) & d_msgbytes) << (d_nbits - d_nresid); + bits = d_resid; + + out[d_subcarrier_map[i]] = d_constellation[bits]; + i++; + + d_bit_offset += d_nresid; + d_nresid = 0; + d_resid = 0; + //printf("mod bit(r): %x resid: %x nresid: %d bit_offset: %d\n", + // bits, d_resid, d_nresid, d_bit_offset); + } + else { + if((8 - d_bit_offset) >= d_nbits) { // test to make sure we can fit nbits + // take the nbits number of bits at a time from the byte to add to the symbol + bits = ((1 << d_nbits)-1) & (d_msgbytes >> d_bit_offset); + d_bit_offset += d_nbits; + + out[d_subcarrier_map[i]] = d_constellation[bits]; + i++; + } + else { // if we can't fit nbits, store them for the next + // saves d_nresid bits of this message where d_nresid < d_nbits + unsigned int extra = 8-d_bit_offset; + d_resid = ((1 << extra)-1) & (d_msgbytes >> d_bit_offset); + d_bit_offset += extra; + d_nresid = d_nbits - extra; + } + } + + if(d_bit_offset == 8) { + d_bit_offset = 0; + d_msg_offset++; + } + } + + // Ran out of data to put in symbol + if (d_msg_offset == d_msg->length()) { + if(d_nresid > 0) { + d_resid |= 0x00; + bits = d_resid; + d_nresid = 0; + d_resid = 0; + } + + //while(i < d_occupied_carriers) { // finish filling out the symbol + while(i < d_subcarrier_map.size()) { // finish filling out the symbol + out[d_subcarrier_map[i]] = d_constellation[randsym()]; + i++; + } + + if(d_msg->type() == 1) // type == 1 sets EOF + d_eof = true; + d_msg.reset(); // finished packet, free message + assert(d_bit_offset == 0); + } + + if(out_flag) + out_flag[0] = d_pending_flag; + d_pending_flag = 0; + + return 1; // produced symbol + } + + } /* namespace digital */ +} /* namespace gr */ diff --git a/gr-digital/lib/ofdm_mapper_bcv_impl.h b/gr-digital/lib/ofdm_mapper_bcv_impl.h new file mode 100644 index 0000000000..6459ed73d8 --- /dev/null +++ b/gr-digital/lib/ofdm_mapper_bcv_impl.h @@ -0,0 +1,74 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_MAPPER_BCV_IMPL_H +#define INCLUDED_DIGITAL_OFDM_MAPPER_BCV_IMPL_H + +#include <digital/ofdm_mapper_bcv.h> +#include <gr_message.h> +#include <vector> + +namespace gr { + namespace digital { + + class ofdm_mapper_bcv_impl : public ofdm_mapper_bcv + { + private: + std::vector<gr_complex> d_constellation; + gr_msg_queue_sptr d_msgq; + gr_message_sptr d_msg; + unsigned d_msg_offset; + bool d_eof; + + unsigned int d_occupied_carriers; + unsigned int d_fft_length; + unsigned int d_bit_offset; + int d_pending_flag; + + unsigned long d_nbits; + unsigned char d_msgbytes; + + unsigned char d_resid; + unsigned int d_nresid; + + std::vector<int> d_subcarrier_map; + + int randsym(); + + public: + ofdm_mapper_bcv_impl(const std::vector<gr_complex> &constellation, + unsigned msgq_limit, + unsigned occupied_carriers, + unsigned int fft_length); + ~ofdm_mapper_bcv_impl(void); + + gr_msg_queue_sptr msgq() const { return d_msgq; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_MAPPER_BCV_IMPL_H */ diff --git a/gr-digital/lib/ofdm_sampler_impl.cc b/gr-digital/lib/ofdm_sampler_impl.cc new file mode 100644 index 0000000000..0724b7cf26 --- /dev/null +++ b/gr-digital/lib/ofdm_sampler_impl.cc @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008,2010-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ofdm_sampler_impl.h" +#include <gr_io_signature.h> +#include <gr_expj.h> +#include <cstdio> + +namespace gr { + namespace digital { + + ofdm_sampler::sptr + ofdm_sampler::make(unsigned int fft_length, + unsigned int symbol_length, + unsigned int timeout) + { + return gnuradio::get_initial_sptr + (new ofdm_sampler_impl(fft_length, symbol_length, timeout)); + } + + ofdm_sampler_impl::ofdm_sampler_impl(unsigned int fft_length, + unsigned int symbol_length, + unsigned int timeout) + : gr_block("ofdm_sampler", + gr_make_io_signature2(2, 2, sizeof(gr_complex), sizeof(char)), + gr_make_io_signature2(2, 2, sizeof(gr_complex)*fft_length, sizeof(char)*fft_length)), + d_state(STATE_NO_SIG), d_timeout_max(timeout), + d_fft_length(fft_length), d_symbol_length(symbol_length) + { + set_relative_rate(1.0/(double) fft_length); // buffer allocator hint + } + + ofdm_sampler_impl::~ofdm_sampler_impl() + { + } + + void + ofdm_sampler_impl::forecast(int noutput_items, gr_vector_int &ninput_items_required) + { + // FIXME do we need more + //int nreqd = (noutput_items-1) * d_symbol_length + d_fft_length; + int nreqd = d_symbol_length + d_fft_length; + unsigned ninputs = ninput_items_required.size(); + for(unsigned i = 0; i < ninputs; i++) + ninput_items_required[i] = nreqd; + } + + int + ofdm_sampler_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 *iptr = (const gr_complex*)input_items[0]; + const char *trigger = (const char*)input_items[1]; + + gr_complex *optr = (gr_complex*)output_items[0]; + char *outsig = (char*)output_items[1]; + + //FIXME: we only process a single OFDM symbol at a time; after the preamble, we can + // process a few at a time as long as we always look out for the next preamble. + + unsigned int index = d_fft_length; // start one fft length into the input so we can always look back this far + + outsig[0] = 0; // set output to no signal by default + + // Search for a preamble trigger signal during the next symbol length + while((d_state != STATE_PREAMBLE) && (index <= (d_symbol_length+d_fft_length))) { + if(trigger[index]) { + outsig[0] = 1; // tell the next block there is a preamble coming + d_state = STATE_PREAMBLE; + } + else + index++; + } + + unsigned int i, pos, ret; + switch(d_state) { + case(STATE_PREAMBLE): + // When we found a preamble trigger, get it and set the symbol boundary here + for(i = (index - d_fft_length + 1); i <= index; i++) { + *optr++ = iptr[i]; + } + + d_timeout = d_timeout_max; // tell the system to expect at least this many symbols for a frame + d_state = STATE_FRAME; + consume_each(index - d_fft_length + 1); // consume up to one fft_length away to keep the history + ret = 1; + break; + + case(STATE_FRAME): + // use this state when we have processed a preamble and are getting the rest of the frames + //FIXME: we could also have a power squelch system here to enter STATE_NO_SIG if no power is received + + // skip over fft length history and cyclic prefix + pos = d_symbol_length; // keeps track of where we are in the input buffer + while(pos < d_symbol_length + d_fft_length) { + *optr++ = iptr[pos++]; + } + + if(d_timeout-- == 0) { + printf("TIMEOUT\n"); + d_state = STATE_NO_SIG; + } + + consume_each(d_symbol_length); // jump up by 1 fft length and the cyclic prefix length + ret = 1; + break; + + case(STATE_NO_SIG): + default: + consume_each(index-d_fft_length); // consume everything we've gone through so far leaving the fft length history + ret = 0; + break; + } + + return ret; + } + + } /* namespace digital */ +} /* namespace gr */ diff --git a/gr-digital/lib/ofdm_sampler_impl.h b/gr-digital/lib/ofdm_sampler_impl.h new file mode 100644 index 0000000000..07b919927e --- /dev/null +++ b/gr-digital/lib/ofdm_sampler_impl.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011,2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_OFDM_SAMPLER_IMPL_H +#define INCLUDED_DIGITAL_OFDM_SAMPLER_IMPL_H + +#include <digital/ofdm_sampler.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + class ofdm_sampler_impl : public ofdm_sampler + { + private: + enum state_t {STATE_NO_SIG, STATE_PREAMBLE, STATE_FRAME}; + + state_t d_state; + unsigned int d_timeout_max; + unsigned int d_timeout; + unsigned int d_fft_length; + unsigned int d_symbol_length; + + public: + ofdm_sampler_impl(unsigned int fft_length, + unsigned int symbol_length, + unsigned int timeout); + ~ofdm_sampler_impl(); + + void forecast(int noutput_items, gr_vector_int &ninput_items_required); + + int general_work(int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_SAMPLER_IMPL_H */ diff --git a/gr-digital/swig/digital_ofdm_frame_acquisition.i b/gr-digital/swig/digital_ofdm_frame_acquisition.i deleted file mode 100644 index b61297bdea..0000000000 --- a/gr-digital/swig/digital_ofdm_frame_acquisition.i +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#include <vector> - -GR_SWIG_BLOCK_MAGIC(digital,ofdm_frame_acquisition); - -digital_ofdm_frame_acquisition_sptr -digital_make_ofdm_frame_acquisition (unsigned int occupied_carriers, - unsigned int fft_length, - unsigned int cplen, - const std::vector<gr_complex> &known_symbol, - unsigned int max_fft_shift_len=4); - -class digital_ofdm_frame_acquisition : public gr_sync_decimator -{ - protected: - digital_ofdm_frame_acquisition (unsigned int occupied_carriers, - unsigned int fft_length, - unsigned int cplen, - const std::vector<gr_complex> &known_symbol, - unsigned int max_fft_shift_len); - - public: - float snr() { return d_snr_est; } - int general_work(int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; diff --git a/gr-digital/swig/digital_ofdm_frame_sink.i b/gr-digital/swig/digital_ofdm_frame_sink.i deleted file mode 100644 index cd3fa14229..0000000000 --- a/gr-digital/swig/digital_ofdm_frame_sink.i +++ /dev/null @@ -1,41 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -GR_SWIG_BLOCK_MAGIC(digital,ofdm_frame_sink); - -digital_ofdm_frame_sink_sptr -digital_make_ofdm_frame_sink(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out, - gr_msg_queue_sptr target_queue, unsigned int occupied_tones, - float phase_gain=0.25, float freq_gain=0.25*0.25/4); - -class digital_ofdm_frame_sink : public gr_sync_block -{ - protected: - digital_ofdm_frame_sink(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out, - gr_msg_queue_sptr target_queue, unsigned int occupied_tones, - float phase_gain, float freq_gain); - - public: - ~digital_ofdm_frame_sink(); -}; diff --git a/gr-digital/swig/digital_ofdm_mapper_bcv.i b/gr-digital/swig/digital_ofdm_mapper_bcv.i deleted file mode 100644 index 4e9aaba7d7..0000000000 --- a/gr-digital/swig/digital_ofdm_mapper_bcv.i +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -GR_SWIG_BLOCK_MAGIC(digital,ofdm_mapper_bcv); - -digital_ofdm_mapper_bcv_sptr -digital_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, - unsigned int msgq_limit, - unsigned int bits_per_symbol, - unsigned int fft_length) throw(std::exception); - - -class digital_ofdm_mapper_bcv : public gr_sync_block -{ - protected: - digital_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, - unsigned int msgq_limit, - unsigned int bits_per_symbol, - unsigned int fft_length); - - public: - gr_msg_queue_sptr msgq(); - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; diff --git a/gr-digital/swig/digital_ofdm_sampler.i b/gr-digital/swig/digital_ofdm_sampler.i deleted file mode 100644 index 91056c320b..0000000000 --- a/gr-digital/swig/digital_ofdm_sampler.i +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2011 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -GR_SWIG_BLOCK_MAGIC(digital,ofdm_sampler) - - digital_ofdm_sampler_sptr digital_make_ofdm_sampler (unsigned int fft_length, - unsigned int symbol_length, - unsigned int timeout=1000); - -class digital_ofdm_sampler : public gr_sync_block -{ - private: - digital_ofdm_sampler (unsigned int fft_length, - unsigned int symbol_length, - unsigned int timeout); -}; diff --git a/gr-digital/swig/digital_swig.i b/gr-digital/swig/digital_swig.i index 1e29280167..b2fe51f58f 100644 --- a/gr-digital/swig/digital_swig.i +++ b/gr-digital/swig/digital_swig.i @@ -74,6 +74,12 @@ #include "digital/map_bb.h" #include "digital/mpsk_receiver_cc.h" #include "digital/mpsk_snr_est_cc.h" +#include "digital/ofdm_cyclic_prefixer.h" +#include "digital/ofdm_frame_acquisition.h" +#include "digital/ofdm_frame_sink.h" +#include "digital/ofdm_insert_preamble.h" +#include "digital/ofdm_mapper_bcv.h" +#include "digital/ofdm_sampler.h" #include "digital/packet_sink.h" #include "digital/pfb_clock_sync_ccf.h" #include "digital/pfb_clock_sync_fff.h" @@ -117,6 +123,12 @@ %include "digital/map_bb.h" %include "digital/mpsk_receiver_cc.h" %include "digital/mpsk_snr_est_cc.h" +%include "digital/ofdm_cyclic_prefixer.h" +%include "digital/ofdm_frame_acquisition.h" +%include "digital/ofdm_frame_sink.h" +%include "digital/ofdm_insert_preamble.h" +%include "digital/ofdm_mapper_bcv.h" +%include "digital/ofdm_sampler.h" %include "digital/packet_sink.h" %include "digital/pfb_clock_sync_ccf.h" %include "digital/pfb_clock_sync_fff.h" @@ -156,6 +168,12 @@ GR_SWIG_BLOCK_MAGIC2(digital, lms_dd_equalizer_cc); GR_SWIG_BLOCK_MAGIC2(digital, map_bb); GR_SWIG_BLOCK_MAGIC2(digital, mpsk_receiver_cc); GR_SWIG_BLOCK_MAGIC2(digital, mpsk_snr_est_cc); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_cyclic_prefixer); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_frame_acquisition); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_frame_sink); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_insert_preamble); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_mapper_bcv); +GR_SWIG_BLOCK_MAGIC2(digital, ofdm_sampler); GR_SWIG_BLOCK_MAGIC2(digital, packet_sink); GR_SWIG_BLOCK_MAGIC2(digital, pfb_clock_sync_ccf); GR_SWIG_BLOCK_MAGIC2(digital, pfb_clock_sync_fff); |