diff options
Diffstat (limited to 'gr-digital/include/digital')
59 files changed, 5501 insertions, 9 deletions
diff --git a/gr-digital/include/digital/CMakeLists.txt b/gr-digital/include/digital/CMakeLists.txt index 104251729..275da16d8 100644 --- a/gr-digital/include/digital/CMakeLists.txt +++ b/gr-digital/include/digital/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2011,2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,17 +22,120 @@ ######################################################################## include(GrPython) +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " +#!${PYTHON_EXECUTABLE} + +import sys, os, re +sys.path.append('${GR_RUNTIME_PYTHONPATH}') +os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' +os.chdir('${CMAKE_CURRENT_BINARY_DIR}') + +if __name__ == '__main__': + import build_utils + root, inp = sys.argv[1:3] + for sig in sys.argv[3:]: + name = re.sub ('X+', sig, root) + d = build_utils.standard_dict2(name, sig, 'digital') + build_utils.expand_template(d, inp) + +") + +macro(expand_h root) + #make a list of all the generated files + unset(expanded_files_h) + foreach(sig ${ARGN}) + string(REGEX REPLACE "X+" ${sig} name ${root}) + list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h) + endforeach(sig) + + #create a command to generate the files + add_custom_command( + OUTPUT ${expanded_files_h} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t + COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} + ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py + ${root} ${root}.h.t ${ARGN} + ) + + #install rules for the generated h files + list(APPEND generated_includes ${expanded_files_h}) +endmacro(expand_h) + +######################################################################## +# Invoke macro to generate various sources +####################################################################### +expand_h(chunks_to_symbols_XX bf bc sf sc if ic) + +add_custom_target(digital_generated_includes DEPENDS + ${generated_includes} +) + ######################################################################## # Install header files ######################################################################## install(FILES + ${generated_includes} + additive_scrambler_bb.h api.h + binary_slicer_fb.h + clock_recovery_mm_cc.h + clock_recovery_mm_ff.h + cma_equalizer_cc.h + constellation.h + constellation_decoder_cb.h + constellation_receiver_cb.h + correlate_access_code_bb.h + correlate_access_code_tag_bb.h + costas_loop_cc.h + cpmmod_bc.h + crc32.h + crc32_bb.h + descrambler_bb.h + diff_decoder_bb.h + diff_encoder_bb.h + diff_phasor_cc.h + fll_band_edge_cc.h + framer_sink_1.h + glfsr.h + glfsr_source_b.h + glfsr_source_f.h + header_payload_demux.h + kurtotic_equalizer_cc.h + lfsr.h + lms_dd_equalizer_cc.h + map_bb.h + metric_type.h + mpsk_receiver_cc.h + mpsk_snr_est.h + mpsk_snr_est_cc.h + ofdm_carrier_allocator_cvc.h + ofdm_chanest_vcvc.h + ofdm_cyclic_prefixer.h + ofdm_equalizer_base.h + ofdm_equalizer_simpledfe.h + ofdm_equalizer_static.h + ofdm_frame_acquisition.h ofdm_frame_equalizer_vcvc.h + ofdm_frame_sink.h + ofdm_insert_preamble.h + ofdm_mapper_bcv.h + ofdm_sampler.h ofdm_serializer_vcc.h + ofdm_sync_sc_cfb.h packet_header_default.h packet_header_ofdm.h packet_headergenerator_bb.h packet_headerparser_b.h + packet_sink.h + pfb_clock_sync_ccf.h + pfb_clock_sync_fff.h + pn_correlator_cc.h + probe_density_b.h + probe_mpsk_snr_est_c.h + scrambler_bb.h + simple_correlator.h + simple_framer.h + simple_framer_sync.h header_payload_demux.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/digital COMPONENT "digital_devel" diff --git a/gr-digital/include/digital/additive_scrambler_bb.h b/gr-digital/include/digital/additive_scrambler_bb.h new file mode 100644 index 000000000..c0ae70e7b --- /dev/null +++ b/gr-digital/include/digital/additive_scrambler_bb.h @@ -0,0 +1,74 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ + +#ifndef INCLUDED_DIGITAL_ADDITIVE_SCRAMBLER_BB_H +#define INCLUDED_DIGITAL_ADDITIVE_SCRAMBLER_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \ingroup coding_blk + * + * \details + * Scramble an input stream using an LFSR. This block works on the + * LSB only of the input data stream, i.e., on an "unpacked + * binary" stream, and produces the same format on its output. + */ + class DIGITAL_API additive_scrambler_bb : virtual public gr_sync_block + { + public: + // gr::digital::additive_scrambler_bb::sptr + typedef boost::shared_ptr<additive_scrambler_bb> sptr; + + /*! + * \brief Create additive scrambler. + * + * Scramble an input stream using an LFSR. This block works on + * the LSB only of the input data stream, i.e., on an "unpacked + * binary" stream, and produces the same format on its output. + * + * \param mask Polynomial mask for LFSR + * \param seed Initial shift register contents + * \param len Shift register length + * \param count Number of bits after which shift register is reset, 0=never + * + * The scrambler works by XORing the incoming bit stream by the + * output of the LFSR. Optionally, after 'count' bits have been + * processed, the shift register is reset to the seed value. + * This allows processing fixed length vectors of samples. + */ + static sptr make(int mask, int seed, int len, int count=0); + + virtual int mask() const = 0; + virtual int seed() const = 0; + virtual int len() const = 0; + virtual int count() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_ADDITIVE_SCRAMBLER_BB_H */ diff --git a/gr-digital/include/digital/api.h b/gr-digital/include/digital/api.h index 0912f7e0d..815f7b662 100644 --- a/gr-digital/include/digital/api.h +++ b/gr-digital/include/digital/api.h @@ -1,5 +1,5 @@ /* - * Copyright 2012 Free Software Foundation, Inc. + * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,7 +22,7 @@ #ifndef INCLUDED_DIGITAL_API_H #define INCLUDED_DIGITAL_API_H -#include <gruel/attributes.h> +#include <attributes.h> #ifdef gnuradio_digital_EXPORTS # define DIGITAL_API __GR_ATTR_EXPORT diff --git a/gr-digital/include/digital/binary_slicer_fb.h b/gr-digital/include/digital/binary_slicer_fb.h new file mode 100644 index 000000000..47e024609 --- /dev/null +++ b/gr-digital/include/digital/binary_slicer_fb.h @@ -0,0 +1,55 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_BINARY_SLICER_FB_H +#define INCLUDED_DIGITAL_BINARY_SLICER_FB_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief slice float binary symbol outputting 1 bit output + * \ingroup symbol_coding_blk + * + * \details + * x < 0 --> 0 + * x >= 0 --> 1 + */ + class DIGITAL_API binary_slicer_fb : virtual public gr_sync_block + { + public: + // gr::digital::binary_slicer_fb::sptr + typedef boost::shared_ptr<binary_slicer_fb> sptr; + + /*! + * \brief Make binary symbol slicer block. + */ + static sptr make(); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_BINARY_SLICER_FB_H */ diff --git a/gr-digital/include/digital/chunks_to_symbols_XX.h.t b/gr-digital/include/digital/chunks_to_symbols_XX.h.t new file mode 100644 index 000000000..6ad10ae26 --- /dev/null +++ b/gr-digital/include/digital/chunks_to_symbols_XX.h.t @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,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. + */ + +/* @WARNING@ */ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <digital/api.h> +#include <gr_sync_interpolator.h> + +namespace gr { + namespace digital { + + /*! + * \brief Map a stream of symbol indexes (unpacked bytes or + * shorts) to stream of float or complex constellation points in D + * dimensions (D = 1 by default) + * \ingroup converter_blk + * + * input: stream of @I_TYPE@; output: stream of @O_TYPE@ + * + * out[n D + k] = symbol_table[in[n] D + k], k=0,1,...,D-1 + * + * The combination of gr::blocks::packed_to_unpacked_XX followed by + * digital_chunks_to_symbols_XY handles the general case of mapping + * from a stream of bytes or shorts into arbitrary float + * or complex symbols. + * + * \sa gr::blocks::packed_to_unpacked_bb, gr::blocks::unpacked_to_packed_bb, + * \sa gr::blocks::packed_to_unpacked_ss, gr::blocks::unpacked_to_packed_ss, + * \sa gr::digital::chunks_to_symbols_bf, gr::digital::chunks_to_symbols_bc. + * \sa gr::digital::chunks_to_symbols_sf, gr::digital::chunks_to_symbols_sc. + */ + + class DIGITAL_API @NAME@ : virtual public gr_sync_interpolator + { + public: + // gr::digital::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! + * Make a chunks-to-symbols block. + * + * \param symbol_table: list that maps chunks to symbols. + * \param D: dimension of table. + */ + static sptr make(const std::vector<@O_TYPE@> &symbol_table, const int D = 1); + + virtual int D() const = 0; + virtual std::vector<@O_TYPE@> symbol_table() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* @GUARD_NAME@ */ diff --git a/gr-digital/include/digital/clock_recovery_mm_cc.h b/gr-digital/include/digital/clock_recovery_mm_cc.h new file mode 100644 index 000000000..a7917e528 --- /dev/null +++ b/gr-digital/include/digital/clock_recovery_mm_cc.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,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_CLOCK_RECOVERY_MM_CC_H +#define INCLUDED_DIGITAL_CLOCK_RECOVERY_MM_CC_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Mueller and Müller (M&M) based clock recovery block with complex input, complex output. + * \ingroup synchronizers_blk + * + * \details + * This implements the Mueller and Müller (M&M) discrete-time + * error-tracking synchronizer. + * + * The complex version here is based on: Modified Mueller and + * Muller clock recovery circuit: + * + * G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller + * and Muller algorithm," Electronics Letters, Vol. 31, no. 13, 22 + * June 1995, pp. 1032 - 1033. + */ + class DIGITAL_API clock_recovery_mm_cc : virtual public gr_block + { + public: + // gr::digital::clock_recovery_mm_cc::sptr + typedef boost::shared_ptr<clock_recovery_mm_cc> sptr; + + /*! + * Make a M&M clock recovery block. + * + * \param omega Initial estimate of samples per symbol + * \param gain_omega Gain setting for omega update loop + * \param mu Initial estimate of phase of sample + * \param gain_mu Gain setting for mu update loop + * \param omega_relative_limit limit on omega + */ + static sptr make(float omega, float gain_omega, + float mu, float gain_mu, + float omega_relative_limit); + + virtual float mu() const = 0; + virtual float omega() const = 0; + virtual float gain_mu() const = 0; + virtual float gain_omega() const = 0; + + virtual void set_verbose(bool verbose) = 0; + virtual void set_gain_mu (float gain_mu) = 0; + virtual void set_gain_omega (float gain_omega) = 0; + virtual void set_mu (float mu) = 0; + virtual void set_omega (float omega) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CLOCK_RECOVERY_MM_CC_H */ diff --git a/gr-digital/include/digital/clock_recovery_mm_ff.h b/gr-digital/include/digital/clock_recovery_mm_ff.h new file mode 100644 index 000000000..491f3ec21 --- /dev/null +++ b/gr-digital/include/digital/clock_recovery_mm_ff.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,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_CLOCK_RECOVERY_MM_FF_H +#define INCLUDED_DIGITAL_CLOCK_RECOVERY_MM_FF_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Mueller and Müller (M&M) based clock recovery block with float input, float output. + * \ingroup synchronizers_blk + * + * \details + * This implements the Mueller and Müller (M&M) discrete-time + * error-tracking synchronizer. + * + * See "Digital Communication Receivers: Synchronization, Channel + * Estimation and Signal Processing" by Heinrich Meyr, Marc + * Moeneclaey, & Stefan Fechtel. ISBN 0-471-50275-8. + */ + class DIGITAL_API clock_recovery_mm_ff : virtual public gr_block + { + public: + // gr::digital::clock_recovery_mm_ff::sptr + typedef boost::shared_ptr<clock_recovery_mm_ff> sptr; + + /*! + * Make a M&M clock recovery block. + * + * \param omega Initial estimate of samples per symbol + * \param gain_omega Gain setting for omega update loop + * \param mu Initial estimate of phase of sample + * \param gain_mu Gain setting for mu update loop + * \param omega_relative_limit limit on omega + */ + static sptr make(float omega, float gain_omega, + float mu, float gain_mu, + float omega_relative_limit); + + virtual float mu() const = 0; + virtual float omega() const = 0; + virtual float gain_mu() const = 0; + virtual float gain_omega() const = 0; + + virtual void set_verbose(bool verbose) = 0; + virtual void set_gain_mu (float gain_mu) = 0; + virtual void set_gain_omega (float gain_omega) = 0; + virtual void set_mu (float mu) = 0; + virtual void set_omega (float omega) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CLOCK_RECOVERY_MM_FF_H */ diff --git a/gr-digital/include/digital/cma_equalizer_cc.h b/gr-digital/include/digital/cma_equalizer_cc.h new file mode 100644 index 000000000..0ccd1c21b --- /dev/null +++ b/gr-digital/include/digital/cma_equalizer_cc.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_CMA_EQUALIZER_CC_H +#define INCLUDED_DIGITAL_CMA_EQUALIZER_CC_H + +#include <digital/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace digital { + + /*! + * \brief Implements constant modulus adaptive filter on complex stream + * \ingroup equalizers_blk + * + * \details + * The error value and tap update equations (for p=2) can be found in: + * + * D. Godard, "Self-Recovering Equalization and Carrier Tracking + * in Two-Dimensional Data Communication Systems," IEEE + * Transactions on Communications, Vol. 28, No. 11, pp. 1867 - + * 1875, 1980. + */ + class DIGITAL_API cma_equalizer_cc: virtual public gr_sync_decimator + { + protected: + virtual gr_complex error(const gr_complex &out) = 0; + virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0; + + public: + // gr::digital::cma_equalizer_cc::sptr + typedef boost::shared_ptr<cma_equalizer_cc> sptr; + + /*! + * Make a CMA Equalizer block + * + * \param num_taps Numer of taps in the equalizer (channel size) + * \param modulus Modulus of the modulated signals + * \param mu Gain of the update loop + * \param sps Number of samples per symbol of the input signal + */ + static sptr make(int num_taps, float modulus, float mu, int sps); + + virtual void set_taps(const std::vector<gr_complex> &taps) = 0; + virtual std::vector<gr_complex> taps() const = 0; + virtual float gain() const = 0; + virtual void set_gain(float mu) = 0; + virtual float modulus() const = 0; + virtual void set_modulus(float mod) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CMA_EQUALIZER_CC_H */ diff --git a/gr-digital/include/digital/constellation.h b/gr-digital/include/digital/constellation.h new file mode 100644 index 000000000..a5e490b42 --- /dev/null +++ b/gr-digital/include/digital/constellation.h @@ -0,0 +1,478 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ + +#ifndef INCLUDED_DIGITAL_CONSTELLATION_H +#define INCLUDED_DIGITAL_CONSTELLATION_H + +#include <digital/api.h> +#include <digital/metric_type.h> +#include <boost/enable_shared_from_this.hpp> +#include <gr_complex.h> +#include <vector> + +namespace gr { + namespace digital { + + /************************************************************/ + /* constellation */ + /* */ + /* Base class defining interface. */ + /************************************************************/ + + class constellation; + typedef boost::shared_ptr<constellation> constellation_sptr; + + /*! + * \brief An abstracted constellation object + * \ingroup symbol_coding_blk + * + * \details + * The constellation objects hold the necessary information to pass + * around constellation information for modulators and + * demodulators. These objects contain the mapping between the bits + * and the constellation points used to represent them as well as + * methods for slicing the symbol space. Various implementations are + * possible for efficiency and ease of use. + * + * Standard constellations (BPSK, QPSK, QAM, etc) can be inherited + * from this class and overloaded to perform optimized slicing and + * constellation mappings. + */ + class DIGITAL_API constellation + : public boost::enable_shared_from_this<constellation> + { + public: + constellation(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int dimensionality); + constellation(); + virtual ~constellation(); + + //! Returns the constellation points for a symbol value + void map_to_points(unsigned int value, gr_complex *points); + std::vector<gr_complex> map_to_points_v(unsigned int value); + + //! Returns the constellation point that matches best. + virtual unsigned int decision_maker(const gr_complex *sample) = 0; + //! Takes a vector rather than a pointer. Better for SWIG wrapping. + unsigned int decision_maker_v(std::vector<gr_complex> sample); + //! Also calculates the phase error. + unsigned int decision_maker_pe(const gr_complex *sample, float *phase_error); + //! Calculates distance. + //unsigned int decision_maker_e(const gr_complex *sample, float *error); + + //! Calculates metrics for all points in the constellation. + //! For use with the viterbi algorithm. + virtual void calc_metric(const gr_complex *sample, float *metric, gr::digital::trellis_metric_type_t type); + virtual void calc_euclidean_metric(const gr_complex *sample, float *metric); + virtual void calc_hard_symbol_metric(const gr_complex *sample, float *metric); + + //! Returns the set of points in this constellation. + std::vector<gr_complex> points() { return d_constellation;} + //! Returns the vector of points in this constellation. + //! Raise error if dimensionality is not one. + std::vector<gr_complex> s_points(); + //! Returns a vector of vectors of points. + std::vector<std::vector<gr_complex> > v_points(); + //! Whether to apply an encoding before doing differential encoding. (e.g. gray coding) + bool apply_pre_diff_code() { return d_apply_pre_diff_code;} + //! Whether to apply an encoding before doing differential encoding. (e.g. gray coding) + void set_pre_diff_code(bool a) { d_apply_pre_diff_code = a;} + //! Returns the encoding to apply before differential encoding. + std::vector<int> pre_diff_code() { return d_pre_diff_code;} + //! Returns the order of rotational symmetry. + unsigned int rotational_symmetry() { return d_rotational_symmetry;} + //! Returns the number of complex numbers in a single symbol. + unsigned int dimensionality() {return d_dimensionality;} + + unsigned int bits_per_symbol() + { + return floor(log(double(d_constellation.size()))/d_dimensionality/log(2.0)); + } + + unsigned int arity() + { + return d_arity; + } + + constellation_sptr base() + { + return shared_from_this(); + } + + protected: + std::vector<gr_complex> d_constellation; + std::vector<int> d_pre_diff_code; + bool d_apply_pre_diff_code; + unsigned int d_rotational_symmetry; + unsigned int d_dimensionality; + unsigned int d_arity; + //! The factor by which the user given constellation points were + //! scaled by to achieve an average amplitude of 1. + float d_scalefactor; + + float get_distance(unsigned int index, const gr_complex *sample); + unsigned int get_closest_point(const gr_complex *sample); + void calc_arity(); + }; + + /************************************************************/ + /* constellation_calcdist */ + /* */ + /************************************************************/ + + /*! \brief Calculate Euclidian distance for any constellation + * \ingroup digital + * + * Constellation which calculates the distance to each point in the + * constellation for decision making. Inefficient for large + * constellations. + */ + class DIGITAL_API constellation_calcdist + : public constellation + { + public: + typedef boost::shared_ptr<constellation_calcdist> sptr; + + // public constructor + static sptr make(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int dimensionality); + + unsigned int decision_maker(const gr_complex *sample); + // void calc_metric(gr_complex *sample, float *metric, trellis_metric_type_t type); + // void calc_euclidean_metric(gr_complex *sample, float *metric); + // void calc_hard_symbol_metric(gr_complex *sample, float *metric); + + protected: + constellation_calcdist(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int dimensionality); + }; + + + /************************************************************/ + /*! constellation_sector */ + /************************************************************/ + + /*! + * \brief Sectorized digital constellation + * \ingroup digital + * + * Constellation space is divided into sectors. Each sector is + * associated with the nearest constellation point. + * + */ + class DIGITAL_API constellation_sector : public constellation + { + public: + + constellation_sector(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int dimensionality, + unsigned int n_sectors); + + ~constellation_sector(); + + unsigned int decision_maker(const gr_complex *sample); + + protected: + virtual unsigned int get_sector(const gr_complex *sample) = 0; + virtual unsigned int calc_sector_value(unsigned int sector) = 0; + void find_sector_values(); + + unsigned int n_sectors; + + private: + std::vector<int> sector_values; + }; + + /************************************************************/ + /* constellation_rect */ + /************************************************************/ + + /*! + * \brief Rectangular digital constellation + * \ingroup digital + * + * Only implemented for 1-(complex)dimensional constellation. + * + * Constellation space is divided into rectangular sectors. Each + * sector is associated with the nearest constellation point. + * + * Works well for square QAM. + * + * Works for any generic constellation provided sectors are not + * too large. + */ + + + class DIGITAL_API constellation_rect + : public constellation_sector + { + public: + typedef boost::shared_ptr<constellation_rect> sptr; + + // public constructor + static constellation_rect::sptr make(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int real_sectors, + unsigned int imag_sectors, + float width_real_sectors, + float width_imag_sectors); + ~constellation_rect(); + + protected: + + constellation_rect(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int real_sectors, + unsigned int imag_sectors, + float width_real_sectors, + float width_imag_sectors); + + unsigned int get_sector(const gr_complex *sample); + + unsigned int calc_sector_value(unsigned int sector); + + private: + unsigned int n_real_sectors; + unsigned int n_imag_sectors; + float d_width_real_sectors; + float d_width_imag_sectors; + }; + + + /************************************************************/ + /* constellation_expl_rect */ + /************************************************************/ + + /*! + * \brief Rectangular digital constellation + * \ingroup digital + * + * Only implemented for 1-(complex)dimensional constellation. + * + * Constellation space is divided into rectangular sectors. Each + * sector is associated with the nearest constellation point. + * + * This class is different from constellation_rect in that the + * mapping from sector to constellation point is explicitly passed + * into the constructor as sector_values. Usually we do not need + * this, since we want each sector to be automatically mapped to + * the closest constellation point, however sometimes it's nice to + * have the flexibility. + */ + class DIGITAL_API constellation_expl_rect + : public constellation_rect + { + public: + typedef boost::shared_ptr<constellation_expl_rect> sptr; + + static sptr make(std::vector<gr_complex> constellation, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int real_sectors, + unsigned int imag_sectors, + float width_real_sectors, + float width_imag_sectors, + std::vector<unsigned int> sector_values); + ~constellation_expl_rect(); + + protected: + constellation_expl_rect(std::vector<gr_complex> constellation, + std::vector<int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int real_sectors, + unsigned int imag_sectors, + float width_real_sectors, + float width_imag_sectors, + std::vector<unsigned int> sector_values); + + unsigned int calc_sector_value (unsigned int sector) { + return d_sector_values[sector]; + } + + private: + std::vector<unsigned int> d_sector_values; + }; + + /************************************************************/ + /* constellation_psk */ + /************************************************************/ + + /*! + * \brief constellation_psk + * \ingroup digital + * + * Constellation space is divided into pie slices sectors. + * + * Each slice is associated with the nearest constellation point. + * + * Works well for PSK but nothing else. + * + * Assumes that there is a constellation point at 1.x + */ + class DIGITAL_API constellation_psk : public constellation_sector + { + public: + typedef boost::shared_ptr<constellation_psk> sptr; + + // public constructor + static sptr make(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int n_sectors); + + ~constellation_psk(); + + protected: + unsigned int get_sector(const gr_complex *sample); + + unsigned int calc_sector_value(unsigned int sector); + + constellation_psk(std::vector<gr_complex> constell, + std::vector<int> pre_diff_code, + unsigned int n_sectors); + }; + + + /************************************************************/ + /* constellation_bpsk */ + /* */ + /* Only works for BPSK. */ + /* */ + /************************************************************/ + + /*! + * \brief Digital constellation for BPSK + * \ingroup digital + */ + class DIGITAL_API constellation_bpsk : public constellation + { + public: + typedef boost::shared_ptr<constellation_bpsk> sptr; + + // public constructor + static sptr make(); + + ~constellation_bpsk(); + + unsigned int decision_maker(const gr_complex *sample); + + protected: + constellation_bpsk(); + }; + + + /************************************************************/ + /* constellation_qpsk */ + /* */ + /* Only works for QPSK. */ + /* */ + /************************************************************/ + + /*! + * \brief Digital constellation for QPSK + * \ingroup digital + */ + class DIGITAL_API constellation_qpsk : public constellation + { + public: + typedef boost::shared_ptr<constellation_qpsk> sptr; + + // public constructor + static sptr make(); + + ~constellation_qpsk(); + + unsigned int decision_maker(const gr_complex *sample); + + protected: + constellation_qpsk(); + }; + + + /************************************************************/ + /* constellation_dqpsk */ + /* */ + /* Works with differential encoding; slower decisions. */ + /* */ + /************************************************************/ + + /*! + * \brief Digital constellation for DQPSK + * \ingroup digital + */ + class DIGITAL_API constellation_dqpsk : public constellation + { + public: + typedef boost::shared_ptr<constellation_dqpsk> sptr; + + // public constructor + static sptr make(); + + ~constellation_dqpsk(); + + unsigned int decision_maker(const gr_complex *sample); + + protected: + constellation_dqpsk(); + }; + + + /************************************************************/ + /* constellation_8psk */ + /* */ + /* Only works for 8PSK. */ + /* */ + /************************************************************/ + + /*! + * \brief Digital constellation for 8PSK + * \ingroup digital + */ + class DIGITAL_API constellation_8psk : public constellation + { + public: + typedef boost::shared_ptr<constellation_8psk> sptr; + + // public constructor + static sptr make(); + + ~constellation_8psk(); + + unsigned int decision_maker(const gr_complex *sample); + + protected: + constellation_8psk(); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CONSTELLATION_H */ diff --git a/gr-digital/include/digital/constellation_decoder_cb.h b/gr-digital/include/digital/constellation_decoder_cb.h new file mode 100644 index 000000000..39cc6ac82 --- /dev/null +++ b/gr-digital/include/digital/constellation_decoder_cb.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_CONSTELLATION_DECODER_CB_H +#define INCLUDED_DIGITAL_CONSTELLATION_DECODER_CB_H + +#include <digital/api.h> +#include <digital/constellation.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Constellation Decoder + * \ingroup symbol_coding_blk + * + * \details + * Decode a constellation's points from a complex space to + * (unpacked) bits based on the map of the \p consetllation + * object. + */ + class DIGITAL_API constellation_decoder_cb + : virtual public gr_block + { + public: + // gr::digital::constellation_decoder_cb::sptr + typedef boost::shared_ptr<constellation_decoder_cb> sptr; + + /*! + * \brief Make constellation decoder block. + * + * \param constellation A constellation derived from class + * 'constellation'. Use base() method to get a shared pointer to + * this base class type. + */ + static sptr make(constellation_sptr constellation); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CONSTELLATION_DECODER_CB_H */ diff --git a/gr-digital/include/digital/constellation_receiver_cb.h b/gr-digital/include/digital/constellation_receiver_cb.h new file mode 100644 index 000000000..0ade7fc21 --- /dev/null +++ b/gr-digital/include/digital/constellation_receiver_cb.h @@ -0,0 +1,92 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_CONSTELLATION_RECEIVER_CB_H +#define INCLUDED_DIGITAL_CONSTELLATION_RECEIVER_CB_H + +#include <digital/api.h> +#include <digital/constellation.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief This block takes care of receiving generic modulated signals + * through phase, frequency, and symbol synchronization. + * \ingroup modulators_blk + * + * \details + * This block takes care of receiving generic modulated signals + * through phase, frequency, and symbol synchronization. It + * performs carrier frequency and phase locking as well as symbol + * timing recovery. + * + * The phase and frequency synchronization are based on a Costas + * loop that finds the error of the incoming signal point compared + * to its nearest constellation point. The frequency and phase of + * the NCO are updated according to this error. + * + * The symbol synchronization is done using a modified Mueller and + * Muller circuit from the paper: + * + * "G. R. Danesfahani, T.G. Jeans, "Optimisation of modified + * Mueller and Muller algorithm," Electronics Letters, Vol. 31, + * no. 13, 22 June 1995, pp. 1032 - 1033." + * + * This circuit interpolates the downconverted sample (using the + * NCO developed by the Costas loop) every mu samples, then it + * finds the sampling error based on this and the past symbols and + * the decision made on the samples. Like the phase error + * detector, there are optimized decision algorithms for BPSK and + * QPKS, but 8PSK uses another brute force computation against all + * possible symbols. The modifications to the M&M used here reduce + * self-noise. + */ + class DIGITAL_API constellation_receiver_cb + : virtual public gr_block + { + public: + // gr::digital::constellation_receiver_cb::sptr + typedef boost::shared_ptr<constellation_receiver_cb> sptr; + + /*! + * \brief Constructor to synchronize incoming M-PSK symbols + * + * \param constellation constellation of points for generic modulation + * \param loop_bw Loop bandwidth of the Costas Loop (~ 2pi/100) + * \param fmin minimum normalized frequency value the loop can achieve + * \param fmax maximum normalized frequency value the loop can achieve + * + * The constructor chooses which phase detector and decision + * maker to use in the work loop based on the value of M. + */ + static sptr make(constellation_sptr constellation, + float loop_bw, float fmin, float fmax); + + virtual void phase_error_tracking(float phase_error) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CONSTELLATION_RECEIVER_CB_H */ diff --git a/gr-digital/include/digital/correlate_access_code_bb.h b/gr-digital/include/digital/correlate_access_code_bb.h new file mode 100644 index 000000000..12c0f3996 --- /dev/null +++ b/gr-digital/include/digital/correlate_access_code_bb.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,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_CORRELATE_ACCESS_CODE_BB_H +#define INCLUDED_DIGITAL_CORRELATE_ACCESS_CODE_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <string> + +namespace gr { + namespace digital { + + /*! + * \brief Examine input for specified access code, one bit at a time. + * \ingroup packet_operators_blk + * \ingroup deprecated_blk + * + * \details + * input: stream of bits, 1 bit per input byte (data in LSB) + * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit) + * + * Each output byte contains two valid bits, the data bit, and the + * flag bit. The LSB (bit 0) is the data bit, and is the original + * input data, delayed 64 bits. Bit 1 is the flag bit and is 1 if + * the corresponding data bit is the first data bit following the + * access code. Otherwise the flag bit is 0. + */ + class DIGITAL_API correlate_access_code_bb : virtual public gr_sync_block + { + public: + // gr::digital::correlate_access_code_bb::sptr + typedef boost::shared_ptr<correlate_access_code_bb> sptr; + + /*! + * Make a correlate_access_code block. + * + * \param access_code is represented with 1 byte per bit, + * e.g., "010101010111000100" + * \param threshold maximum number of bits that may be wrong + */ + static sptr make(const std::string &access_code, int threshold); + + /*! + * Set a new access code. + * + * \param access_code is represented with 1 byte per bit, + * e.g., "010101010111000100" + */ + virtual bool set_access_code(const std::string &access_code) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CORRELATE_ACCESS_CODE_BB_H */ diff --git a/gr-digital/include/digital/correlate_access_code_tag_bb.h b/gr-digital/include/digital/correlate_access_code_tag_bb.h new file mode 100644 index 000000000..5e04aa0b6 --- /dev/null +++ b/gr-digital/include/digital/correlate_access_code_tag_bb.h @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,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_CORRELATE_ACCESS_CODE_TAG_BB_H +#define INCLUDED_DIGITAL_CORRELATE_ACCESS_CODE_TAG_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <string> + +namespace gr { + namespace digital { + + /*! + * \brief Examine input for specified access code, one bit at a time. + * \ingroup packet_operators_blk + * + * \details + * input: stream of bits, 1 bit per input byte (data in LSB) + * output: unaltered stream of bits (plus tags) + * + * This block annotates the input stream with tags. The tags have + * key name [tag_name], specified in the constructor. Used for + * searching an input data stream for preambles, etc. + */ + class DIGITAL_API correlate_access_code_tag_bb : virtual public gr_sync_block + { + public: + // gr::digital::correlate_access_code_tag_bb::sptr + typedef boost::shared_ptr<correlate_access_code_tag_bb> sptr; + + /*! + * \param access_code is represented with 1 byte per bit, + * e.g., "010101010111000100" + * \param threshold maximum number of bits that may be wrong + * \param tag_name key of the tag inserted into the tag stream + */ + static sptr make(const std::string &access_code, + int threshold, + const std::string &tag_name); + + /*! + * \param access_code is represented with 1 byte per bit, + * e.g., "010101010111000100" + */ + virtual bool set_access_code(const std::string &access_code) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CORRELATE_ACCESS_CODE_TAG_BB_H */ diff --git a/gr-digital/include/digital/costas_loop_cc.h b/gr-digital/include/digital/costas_loop_cc.h new file mode 100644 index 000000000..8ac0444cb --- /dev/null +++ b/gr-digital/include/digital/costas_loop_cc.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_COSTAS_LOOP_CC_H +#define INCLUDED_DIGITAL_COSTAS_LOOP_CC_H + +#include <digital/api.h> +#include <blocks/control_loop.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief A Costas loop carrier recovery module. + * \ingroup synchronizers_blk + * + * \details + * The Costas loop locks to the center frequency of a signal and + * downconverts it to baseband. The second (order=2) order loop + * is used for BPSK where the real part of the output signal is + * the baseband BPSK signal and the imaginary part is the error + * signal. When order=4, it can be used for quadrature + * modulations where both I and Q (real and imaginary) are + * outputted. + * + * More details can be found online: + * + * J. Feigin, "Practical Costas loop design: Designing a simple + * and inexpensive BPSK Costas loop carrier recovery circuit," RF + * signal processing, pp. 20-36, 2002. + * + * http://rfdesign.com/images/archive/0102Feigin20.pdf + * + * The Costas loop can have two output streams: + * stream 1 is the baseband I and Q; + * stream 2 is the normalized frequency of the loop + */ + class DIGITAL_API costas_loop_cc + : virtual public gr_sync_block, + virtual public blocks::control_loop + { + public: + // gr::digital::costas_loop_cc::sptr + typedef boost::shared_ptr<costas_loop_cc> sptr; + + /*! + * Make a Costas loop carrier recovery block. + * + * \param loop_bw internal 2nd order loop bandwidth (~ 2pi/100) + * \param order the loop order, either 2, 4, or 8 + */ + static sptr make(float loop_bw, int order); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_COSTAS_LOOP_CC_H */ diff --git a/gr-digital/include/digital/cpmmod_bc.h b/gr-digital/include/digital/cpmmod_bc.h new file mode 100644 index 000000000..85fb0fae8 --- /dev/null +++ b/gr-digital/include/digital/cpmmod_bc.h @@ -0,0 +1,117 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ + +#ifndef INCLUDED_DIGITAL_CPMMOD_BC_H +#define INCLUDED_DIGITAL_CPMMOD_BC_H + +#include <digital/api.h> +#include <gr_hier_block2.h> +#include <analog/cpm.h> + +namespace gr { + namespace digital { + + /*! + * \brief Generic CPM modulator + * \ingroup modulators_blk + * + * \details + * Examples: + * - Setting h = 0.5, L = 1, type = LREC yields MSK. + * - Setting h = 0.5, type = GAUSSIAN and beta = 0.3 yields GMSK + * as used in GSM. + * + * The input of this block are symbols from an M-ary alphabet + * +/-1, +/-3, ..., +/-(M-1). Usually, M = 2 and therefore, the + * valid inputs are +/-1. + * The modulator will silently accept any other inputs, though. + * The output is the phase-modulated signal. + */ + class DIGITAL_API cpmmod_bc : virtual public gr_hier_block2 + { + public: + // gr::digital::cpmmod_bc::sptr + typedef boost::shared_ptr<cpmmod_bc> sptr; + + /*! + * Make CPM modulator block. + * + * \param type The modulation type. Can be one of LREC, LRC, LSRC, TFM + * or GAUSSIAN. See gr_cpm::phase_response() for a + * detailed description. + * \param h The modulation index. \f$ h \cdot \pi\f$ is the maximum + * phase change that can occur between two symbols, i.e., if + * you only send ones, the phase will increase by \f$ h \cdot + * \pi\f$ every \p samples_per_sym samples. Set this to 0.5 + * for Minimum Shift Keying variants. + * \param samples_per_sym Samples per symbol. + * \param L The length of the phase duration in symbols. For L=1, this + * yields full- response CPM symbols, for L > 1, + * partial-response. + * \param beta For LSRC, this is the rolloff factor. For Gaussian + * pulses, this is the 3 dB time-bandwidth product. + */ + static sptr make(analog::cpm::cpm_type type, float h, + int samples_per_sym, + int L, double beta=0.3); + + /*! + * Make GMSK modulator block. + * + * The type is GAUSSIAN and the modulation index for GMSK is + * 0.5. This are populated automatically by this factory + * function. + * + * \param samples_per_sym Samples per symbol. + * \param L The length of the phase duration in symbols. For L=1, this + * yields full- response CPM symbols, for L > 1, + * partial-response. + * \param beta For LSRC, this is the rolloff factor. For Gaussian + * pulses, this is the 3 dB time-bandwidth product. + */ + static sptr make_gmskmod_bc(int samples_per_sym=2, + int L=4, double beta=0.3); + + //! Return the phase response FIR taps + virtual std::vector<float> taps() const = 0; + + //! Return the type of CPM modulator + virtual int type() const = 0; + + //! Return the modulation index of the modulator. + virtual float index() const = 0; + + //! Return the number of samples per symbol + virtual int samples_per_sym() const = 0; + + //! Return the length of the phase duration (in symbols) + virtual int length() const = 0; + + //! Return the value of beta for the modulator + virtual double beta() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_CPMMOD_BC_H */ + diff --git a/gr-digital/include/digital/crc32.h b/gr-digital/include/digital/crc32.h new file mode 100644 index 000000000..180719bf7 --- /dev/null +++ b/gr-digital/include/digital/crc32.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,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_CRC32_H +#define INCLUDED_DIGITAL_CRC32_H + +#include <digital/api.h> +#include <string> +#include <gr_types.h> + +namespace gr { + namespace digital { + + /*! + * \brief update running CRC-32 + * \ingroup packet_operators_blk + * + * \details + * Update a running CRC with the bytes buf[0..len-1] The CRC + * should be initialized to all 1's, and the transmitted value is + * the 1's complement of the final running CRC. The resulting CRC + * should be transmitted in big endian order. + */ + DIGITAL_API unsigned int + update_crc32(unsigned int crc, const unsigned char *buf, size_t len); + + DIGITAL_API unsigned int + update_crc32(unsigned int crc, const std::string buf); + + DIGITAL_API unsigned int + crc32(const unsigned char *buf, size_t len); + + DIGITAL_API unsigned int + crc32(const std::string buf); + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_CRC32_H */ diff --git a/gr-digital/include/digital/crc32_bb.h b/gr-digital/include/digital/crc32_bb.h new file mode 100644 index 000000000..52f056c71 --- /dev/null +++ b/gr-digital/include/digital/crc32_bb.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 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_CRC32_BB_H +#define INCLUDED_DIGITAL_CRC32_BB_H + +#include <digital/api.h> +#include <gr_tagged_stream_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Byte-stream CRC block + * \ingroup packet_operators_blk + * + * \details + * Input: stream of bytes, which form a packet. The first byte of the packet + * has a tag with key "length" and the value being the number of bytes in the + * packet. + * + * Output: The same bytes as incoming, but trailing a CRC32 of the packet. + * The tag is re-set to the new length. + */ + class DIGITAL_API crc32_bb : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<crc32_bb> sptr; + + /*! + * \param check Set to true if you want to check CRC, false to create CRC. + * \param lengthtagname Length tag key + */ + static sptr make(bool check=false, const std::string& lengthtagname="packet_len"); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_CRC32_BB_H */ + diff --git a/gr-digital/include/digital/descrambler_bb.h b/gr-digital/include/digital/descrambler_bb.h new file mode 100644 index 000000000..da8a3b0e8 --- /dev/null +++ b/gr-digital/include/digital/descrambler_bb.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,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_GR_DESCRAMBLER_BB_H +#define INCLUDED_GR_DESCRAMBLER_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Descramber an input stream using an LFSR. + * \ingroup coding_blk + * + * \details + * Descramble an input stream using an LFSR. This block works on + * the LSB only of the input data stream, i.e., on an "unpacked + * binary" stream, and produces the same format on its output. + */ + class DIGITAL_API descrambler_bb : virtual public gr_sync_block + { + public: + // gr::digital::descrambler_bb::sptr + typedef boost::shared_ptr<descrambler_bb> sptr; + + /*! + * Descramble an input stream using an LFSR. This block works on + * the LSB only of the input data stream, i.e., on an "unpacked + * binary" stream, and produces the same format on its output. + * + * \param mask Polynomial mask for LFSR + * \param seed Initial shift register contents + * \param len Shift register length + */ + static sptr make(int mask, int seed, int len); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_DESCRAMBLER_BB_H */ diff --git a/gr-digital/include/digital/diff_decoder_bb.h b/gr-digital/include/digital/diff_decoder_bb.h new file mode 100644 index 000000000..0b28b2a55 --- /dev/null +++ b/gr-digital/include/digital/diff_decoder_bb.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,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_GR_DIFF_DECODER_BB_H +#define INCLUDED_GR_DIFF_DECODER_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Differential encoder: y[0] = (x[0] - x[-1]) % M + * \ingroup symbol_coding_blk + * + * \details + * Uses current and previous symbols and the alphabet modulus to + * perform differential decoding. + */ + class DIGITAL_API diff_decoder_bb : virtual public gr_sync_block + { + public: + // gr::digital::diff_decoder_bb::sptr + typedef boost::shared_ptr<diff_decoder_bb> sptr; + + /*! + * Make a differntial decoder block. + * + * \param modulus Modulus of code's alphabet + */ + static sptr make(unsigned int modulus); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_DIFF_DECODER_BB_H */ diff --git a/gr-digital/include/digital/diff_encoder_bb.h b/gr-digital/include/digital/diff_encoder_bb.h new file mode 100644 index 000000000..ef9d0970a --- /dev/null +++ b/gr-digital/include/digital/diff_encoder_bb.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,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_GR_DIFF_ENCODER_BB_H +#define INCLUDED_GR_DIFF_ENCODER_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Differential decoder: y[0] = (x[0] + y[-1]) % M + * \ingroup symbol_coding_blk + * + * \details + * Uses current and previous symbols and the alphabet modulus to + * perform differential encoding. + */ + class DIGITAL_API diff_encoder_bb : virtual public gr_sync_block + { + public: + // gr::digital::diff_encoder_bb::sptr + typedef boost::shared_ptr<diff_encoder_bb> sptr; + + /*! + * Make a differntial encoder block. + * + * \param modulus Modulus of code's alphabet + */ + static sptr make(unsigned int modulus); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_DIFF_ENCODER_BB_H */ diff --git a/gr-digital/include/digital/diff_phasor_cc.h b/gr-digital/include/digital/diff_phasor_cc.h new file mode 100644 index 000000000..e2bf2bce5 --- /dev/null +++ b/gr-digital/include/digital/diff_phasor_cc.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,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_GR_DIFF_PHASOR_CC_H +#define INCLUDED_GR_DIFF_PHASOR_CC_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Differential decoding based on phase change. + * \ingroup symbol_coding_blk + * + * \details + * Uses the phase difference between two symbols to determine the + * output symbol: + * + * out[i] = in[i] * conj(in[i-1]); + */ + class DIGITAL_API diff_phasor_cc : virtual public gr_sync_block + { + public: + // gr::digital::diff_phasor_cc::sptr + typedef boost::shared_ptr<diff_phasor_cc> sptr; + + /*! + * Make a differential phasor decoding block. + */ + static sptr make(); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_DIFF_PHASOR_CC_H */ diff --git a/gr-digital/include/digital/fll_band_edge_cc.h b/gr-digital/include/digital/fll_band_edge_cc.h new file mode 100644 index 000000000..0bf347111 --- /dev/null +++ b/gr-digital/include/digital/fll_band_edge_cc.h @@ -0,0 +1,179 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,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_FLL_BAND_EDGE_CC_H +#define INCLUDED_DIGITAL_FLL_BAND_EDGE_CC_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <blocks/control_loop.h> + +namespace gr { + namespace digital { + + /*! + * \brief Frequency Lock Loop using band-edge filters + * \ingroup synchronizers_blk + * + * \details + * The frequency lock loop derives a band-edge filter that covers + * the upper and lower bandwidths of a digitally-modulated + * signal. The bandwidth range is determined by the excess + * bandwidth (e.g., rolloff factor) of the modulated signal. The + * placement in frequency of the band-edges is determined by the + * oversampling ratio (number of samples per symbol) and the + * excess bandwidth. The size of the filters should be fairly + * large so as to average over a number of symbols. + * + * The FLL works by filtering the upper and lower band edges into + * x_u(t) and x_l(t), respectively. These are combined to form + * cc(t) = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining + * these to form the signal e(t) = Re{cc(t) \\times ss(t)^*} + * (where ^* is the complex conjugate) provides an error signal at + * the DC term that is directly proportional to the carrier + * frequency. We then make a second-order loop using the error + * signal that is the running average of e(t). + * + * In practice, the above equation can be simplified by just + * comparing the absolute value squared of the output of both + * filters: abs(x_l(t))^2 - abs(x_u(t))^2 = norm(x_l(t)) - + * norm(x_u(t)). + * + * In theory, the band-edge filter is the derivative of the + * matched filter in frequency, (H_be(f) = frac{H(f)}{df}). In + * practice, this comes down to a quarter sine wave at the point + * of the matched filter's rolloff (if it's a raised-cosine, the + * derivative of a cosine is a sine). Extend this sine by another + * quarter wave to make a half wave around the band-edges is + * equivalent in time to the sum of two sinc functions. The + * baseband filter fot the band edges is therefore derived from + * this sum of sincs. The band edge filters are then just the + * baseband signal modulated to the correct place in + * frequency. All of these calculations are done in the + * 'design_filter' function. + * + * Note: We use FIR filters here because the filters have to have + * a flat phase response over the entire frequency range to allow + * their comparisons to be valid. + * + * It is very important that the band edge filters be the + * derivatives of the pulse shaping filter, and that they be + * linear phase. Otherwise, the variance of the error will be very + * large. + */ + class DIGITAL_API fll_band_edge_cc + : virtual public gr_sync_block, + virtual public blocks::control_loop + { + public: + // gr::digital::fll_band_edge_cc::sptr + typedef boost::shared_ptr<fll_band_edge_cc> sptr; + + /*! + * Make an FLL block. + * + * \param samps_per_sym (float) number of samples per symbol + * \param rolloff (float) Rolloff (excess bandwidth) of signal filter + * \param filter_size (int) number of filter taps to generate + * \param bandwidth (float) Loop bandwidth + */ + static sptr make(float samps_per_sym, float rolloff, + int filter_size, float bandwidth); + + /******************************************************************* + SET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Set the number of samples per symbol + * + * Set's the number of samples per symbol the system should + * use. This value is uesd to calculate the filter taps and will + * force a recalculation. + * + * \param sps (float) new samples per symbol + */ + virtual void set_samples_per_symbol(float sps) = 0; + + /*! + * \brief Set the rolloff factor of the shaping filter + * + * This sets the rolloff factor that is used in the pulse + * shaping filter and is used to calculate the filter + * taps. Changing this will force a recalculation of the filter + * taps. + * + * This should be the same value that is used in the + * transmitter's pulse shaping filter. It must be between 0 and + * 1 and is usually between 0.2 and 0.5 (where 0.22 and 0.35 are + * commonly used values). + * + * \param rolloff (float) new shaping filter rolloff factor [0,1] + */ + virtual void set_rolloff(float rolloff) = 0; + + /*! + * \brief Set the number of taps in the filter + * + * This sets the number of taps in the band-edge + * filters. Setting this will force a recalculation of the + * filter taps. + * + * This should be about the same number of taps used in the + * transmitter's shaping filter and also not very large. A large + * number of taps will result in a large delay between input and + * frequency estimation, and so will not be as accurate. Between + * 30 and 70 taps is usual. + * + * \param filter_size (float) number of taps in the filters + */ + virtual void set_filter_size(int filter_size) = 0; + + /******************************************************************* + GET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Returns the number of sampler per symbol used for the filter + */ + virtual float samples_per_symbol() const = 0; + + /*! + * \brief Returns the rolloff factor used for the filter + */ + virtual float rolloff() const = 0; + + /*! + * \brief Returns the number of taps of the filter + */ + virtual int filter_size() const = 0; + + /*! + * Print the taps to screen. + */ + virtual void print_taps() = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_FLL_BAND_EDGE_CC_H */ diff --git a/gr-digital/include/digital/framer_sink_1.h b/gr-digital/include/digital/framer_sink_1.h new file mode 100644 index 000000000..b56277870 --- /dev/null +++ b/gr-digital/include/digital/framer_sink_1.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,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_GR_FRAMER_SINK_1_H +#define INCLUDED_GR_FRAMER_SINK_1_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <gr_msg_queue.h> + +namespace gr { + namespace digital { + + /*! + * \brief Given a stream of bits and access_code flags, assemble packets. + * \ingroup packet_operators_blk + * + * \details + * input: stream of bytes from digital_correlate_access_code_bb + * output: none. Pushes assembled packet into target queue + * + * The framer expects a fixed length header of 2 16-bit shorts + * containing the payload length, followed by the payload. If the + * 2 16-bit shorts are not identical, this packet is + * ignored. Better algs are welcome. + * + * The input data consists of bytes that have two bits used. Bit + * 0, the LSB, contains the data bit. Bit 1 if set, indicates that + * the corresponding bit is the the first bit of the packet. That + * is, this bit is the first one after the access code. + */ + class DIGITAL_API framer_sink_1 : virtual public gr_sync_block + { + public: + // gr::digital::framer_sink_1::sptr + typedef boost::shared_ptr<framer_sink_1> sptr; + + /*! + * Make a framer_sink_1 block. + * + * \param target_queue The message queue where frames go. + */ + static sptr make(gr_msg_queue_sptr target_queue); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_FRAMER_SINK_1_H */ diff --git a/gr-digital/include/digital/glfsr.h b/gr-digital/include/digital/glfsr.h new file mode 100644 index 000000000..4c7701d7e --- /dev/null +++ b/gr-digital/include/digital/glfsr.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,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_GLFSR_H +#define INCLUDED_DIGITAL_GLFSR_H + +#include <digital/api.h> + +namespace gr { + namespace digital { + + /*! + * \brief Galois Linear Feedback Shift Register using specified polynomial mask + * \ingroup waveform_generators_blk + * + * \details + * Generates a maximal length pseudo-random sequence of length 2^degree-1 + */ + class DIGITAL_API glfsr + { + private: + int d_shift_register; + int d_mask; + + public: + glfsr(int mask, int seed) { d_shift_register = seed; d_mask = mask; } + ~glfsr(); + + static int glfsr_mask(int degree); + + unsigned char next_bit() + { + unsigned char bit = d_shift_register & 1; + d_shift_register >>= 1; + if(bit) + d_shift_register ^= d_mask; + return bit; + } + + int mask() const { return d_mask; } + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_GLFSR_H */ diff --git a/gr-digital/include/digital/glfsr_source_b.h b/gr-digital/include/digital/glfsr_source_b.h new file mode 100644 index 000000000..7fefb747a --- /dev/null +++ b/gr-digital/include/digital/glfsr_source_b.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,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_GR_GLFSR_SOURCE_B_H +#define INCLUDED_GR_GLFSR_SOURCE_B_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Galois LFSR pseudo-random source + * \ingroup waveform_generators_blk + */ + class DIGITAL_API glfsr_source_b : virtual public gr_sync_block + { + public: + // gr::digital::glfsr_source_b::sptr + typedef boost::shared_ptr<glfsr_source_b> sptr; + + /*! + * Make a Galois LFSR pseudo-random source block. + * + * \param degree Degree of shift register must be in [1, 32]. If mask + * is 0, the degree determines a default mask (see + * digital_impl_glfsr.cc for the mapping). + * \param repeat Set to repeat sequence. + * \param mask Allows a user-defined bit mask for indexes of the shift + * register to feed back. + * \param seed Initial setting for values in shift register. + */ + static sptr make(int degree, bool repeat=true, + int mask=0, int seed=1); + + virtual unsigned int period() const = 0; + virtual int mask() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_GLFSR_SOURCE_B_H */ diff --git a/gr-digital/include/digital/glfsr_source_f.h b/gr-digital/include/digital/glfsr_source_f.h new file mode 100644 index 000000000..e591498d8 --- /dev/null +++ b/gr-digital/include/digital/glfsr_source_f.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,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_GR_GLFSR_SOURCE_F_H +#define INCLUDED_GR_GLFSR_SOURCE_F_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Galois LFSR pseudo-random source generating float outputs -1.0 - 1.0. + * \ingroup waveform_generators_blk + */ + class DIGITAL_API glfsr_source_f : virtual public gr_sync_block + { + public: + // gr::digital::glfsr_source_f::sptr + typedef boost::shared_ptr<glfsr_source_f> sptr; + + /*! + * Make a Galois LFSR pseudo-random source block. + * + * \param degree Degree of shift register must be in [1, 32]. If mask + * is 0, the degree determines a default mask (see + * digital_impl_glfsr.cc for the mapping). + * \param repeat Set to repeat sequence. + * \param mask Allows a user-defined bit mask for indexes of the shift + * register to feed back. + * \param seed Initial setting for values in shift register. + */ + static sptr make(int degree, bool repeat=true, + int mask=0, int seed=1); + + virtual unsigned int period() const = 0; + virtual int mask() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_GLFSR_SOURCE_F_H */ diff --git a/gr-digital/include/digital/kurtotic_equalizer_cc.h b/gr-digital/include/digital/kurtotic_equalizer_cc.h new file mode 100644 index 000000000..d32533b76 --- /dev/null +++ b/gr-digital/include/digital/kurtotic_equalizer_cc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_KURTOTIC_EQUALIZER_CC_H +#define INCLUDED_DIGITAL_KURTOTIC_EQUALIZER_CC_H + +#include <digital/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace digital { + + /*! + * \brief Implements a kurtosis-based adaptive equalizer on complex stream + * \ingroup equalizers_blk + * + * \details + * WARNING: This block does not yet work. + * + * "Y. Guo, J. Zhao, Y. Sun, "Sign kurtosis maximization based blind + * equalization algorithm," IEEE Conf. on Control, Automation, + * Robotics and Vision, Vol. 3, Dec. 2004, pp. 2052 - 2057." + */ + class DIGITAL_API kurtotic_equalizer_cc : + virtual public gr_sync_decimator + { + protected: + virtual gr_complex error(const gr_complex &out) = 0; + virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0; + + public: + // gr::digital::kurtotic_equalizer_cc::sptr + typedef boost::shared_ptr<kurtotic_equalizer_cc> sptr; + + static sptr make(int num_taps, float mu); + + virtual float gain() const = 0; + virtual void set_gain(float mu) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_KURTOTIC_EQUALIZER_CC_H */ diff --git a/gr-digital/include/digital/lfsr.h b/gr-digital/include/digital/lfsr.h new file mode 100644 index 000000000..0dd419b79 --- /dev/null +++ b/gr-digital/include/digital/lfsr.h @@ -0,0 +1,163 @@ +/* -*- c++ -*- */ +/* + * Copyright 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. + */ + +#ifndef INCLUDED_DIGITAL_LFSR_H +#define INCLUDED_DIGITAL_LFSR_H + +#include <digital/api.h> +#include <stdexcept> +#include <stdint.h> + +namespace gr { + namespace digital { + + /*! + * \brief Fibonacci Linear Feedback Shift Register using specified + * polynomial mask + * \ingroup misc + * + * \details + * Generates a maximal length pseudo-random sequence of length + * 2^degree-1 + * + * Constructor: digital::lfsr(int mask, int seed, int reg_len); + * + * \param mask - polynomial coefficients representing the + * locations of feedback taps from a shift register + * which are xor'ed together to form the new high + * order bit. + * + * Some common masks might be: + * x^4 + x^3 + x^0 = 0x19 + * x^5 + x^3 + x^0 = 0x29 + * x^6 + x^5 + x^0 = 0x61 + * + * \param seed - the initialization vector placed into the + * register durring initialization. Low order bit + * corresponds to x^0 coefficient -- the first to be + * shifted as output. + * + * \param reg_len - specifies the length of the feedback shift + * register to be used. Durring each iteration, the + * register is rightshifted one and the new bit is + * placed in bit reg_len. reg_len should generally be + * at least order(mask) + 1 + * + * + * see http://en.wikipedia.org/wiki/Linear_feedback_shift_register + * for more explanation. + * + * next_bit() - Standard LFSR operation + * + * Perform one cycle of the LFSR. The output bit is taken from + * the shift register LSB. The shift register MSB is assigned from + * the modulo 2 sum of the masked shift register. + * + * next_bit_scramble(unsigned char input) - Scramble an input stream + * + * Perform one cycle of the LFSR. The output bit is taken from + * the shift register LSB. The shift register MSB is assigned from + * the modulo 2 sum of the masked shift register and the input LSB. + * + * next_bit_descramble(unsigned char input) - Descramble an input stream + * + * Perform one cycle of the LFSR. The output bit is taken from + * the modulo 2 sum of the masked shift register and the input LSB. + * The shift register MSB is assigned from the LSB of the input. + * + * See http://en.wikipedia.org/wiki/Scrambler for operation of these + * last two functions (see multiplicative scrambler.) + */ + class lfsr + { + private: + uint32_t d_shift_register; + uint32_t d_mask; + uint32_t d_seed; + uint32_t d_shift_register_length; // less than 32 + + static uint32_t + popCount(uint32_t x) + { + uint32_t r = x - ((x >> 1) & 033333333333) + - ((x >> 2) & 011111111111); + return ((r + (r >> 3)) & 030707070707) % 63; + } + + public: + lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len) + : d_shift_register(seed), + d_mask(mask), + d_seed(seed), + d_shift_register_length(reg_len) + { + if(reg_len > 31) + throw std::invalid_argument("reg_len must be <= 31"); + } + + unsigned char next_bit() + { + unsigned char output = d_shift_register & 1; + unsigned char newbit = popCount( d_shift_register & d_mask )%2; + d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); + return output; + } + + unsigned char next_bit_scramble(unsigned char input) + { + unsigned char output = d_shift_register & 1; + unsigned char newbit = (popCount( d_shift_register & d_mask )%2)^(input & 1); + d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); + return output; + } + + unsigned char next_bit_descramble(unsigned char input) + { + unsigned char output = (popCount( d_shift_register & d_mask )%2)^(input & 1); + unsigned char newbit = input & 1; + d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); + return output; + } + + /*! + * Reset shift register to initial seed value + */ + void reset() { d_shift_register = d_seed; } + + /*! + * Rotate the register through x number of bits + * where we are just throwing away the results to get queued up correctly + */ + void pre_shift(int num) + { + for(int i=0; i<num; i++) { + next_bit(); + } + } + + int mask() const { return d_mask; } + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_LFSR_H */ diff --git a/gr-digital/include/digital/lms_dd_equalizer_cc.h b/gr-digital/include/digital/lms_dd_equalizer_cc.h new file mode 100644 index 000000000..7286c9ad3 --- /dev/null +++ b/gr-digital/include/digital/lms_dd_equalizer_cc.h @@ -0,0 +1,101 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_LMS_DD_EQUALIZER_CC_H +#define INCLUDED_DIGITAL_LMS_DD_EQUALIZER_CC_H + +#include <digital/api.h> +#include <gr_sync_decimator.h> +#include <digital/constellation.h> + +namespace gr { + namespace digital { + + /*! + * \brief Least-Mean-Square Decision Directed Equalizer (complex in/out) + * \ingroup equalizers_blk + * + * \details + * This block implements an LMS-based decision-directed equalizer. + * It uses a set of weights, w, to correlate against the inputs, + * u, and a decisions is then made from this output. The error in + * the decision is used to update teh weight vector. + * + * y[n] = conj(w[n]) u[n] + * d[n] = decision(y[n]) + * e[n] = d[n] - y[n] + * w[n+1] = w[n] + mu u[n] conj(e[n]) + * + * Where mu is a gain value (between 0 and 1 and usualy small, + * around 0.001 - 0.01. + * + * This block uses the digital_constellation object for making the + * decision from y[n]. Create the constellation object for + * whatever constellation is to be used and pass in the object. + * In Python, you can use something like: + * + * self.constellation = digital.constellation_qpsk() + * + * To create a QPSK constellation (see the digital_constellation + * block for more details as to what constellations are available + * or how to create your own). You then pass the object to this + * block as an sptr, or using "self.constellation.base()". + * + * The theory for this algorithm can be found in Chapter 9 of: + * S. Haykin, Adaptive Filter Theory, Upper Saddle River, NJ: + * Prentice Hall, 1996. + */ + class DIGITAL_API lms_dd_equalizer_cc : + virtual public gr_sync_decimator + { + protected: + virtual gr_complex error(const gr_complex &out) = 0; + virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0; + + public: + // gr::digital::lms_dd_equalizer_cc::sptr + typedef boost::shared_ptr<lms_dd_equalizer_cc> sptr; + + /*! + * Make an LMS decision-directed equalizer + * + * \param num_taps Numer of taps in the equalizer (channel size) + * \param mu Gain of the update loop + * \param sps Number of samples per symbol of the input signal + * \param cnst A constellation derived from class + * 'constellation'. Use base() method to get a shared pointer to + * this base class type. + */ + static sptr make(int num_taps, + float mu, int sps, + constellation_sptr cnst); + + virtual void set_taps(const std::vector<gr_complex> &taps) = 0; + virtual std::vector<gr_complex> taps() const = 0; + virtual float gain() const = 0; + virtual void set_gain(float mu) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_LMS_DD_EQUALIZER_CC_H */ diff --git a/gr-digital/include/digital/map_bb.h b/gr-digital/include/digital/map_bb.h new file mode 100644 index 000000000..0a55a6121 --- /dev/null +++ b/gr-digital/include/digital/map_bb.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,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_GR_MAP_BB_H +#define INCLUDED_GR_MAP_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief output[i] = map[input[i]] + * \ingroup symbol_coding_blk + * + * \details + * This block maps an incoming signal to the value in the map. + * The block expects that the incoming signal has a maximum + * value of len(map)-1. + * + * -> output[i] = map[input[i]] + */ + class DIGITAL_API map_bb : virtual public gr_sync_block + { + public: + // gr::digital::map_bb::sptr + typedef boost::shared_ptr<map_bb> sptr; + + /*! + * Make a map block. + * + * \param map a vector of integers that maps x to map[x]. + */ + static sptr make(const std::vector<int> &map); + + virtual void set_map(const std::vector<int> &map) = 0; + virtual std::vector<int> map() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_MAP_BB_H */ diff --git a/gr-digital/include/digital/metric_type.h b/gr-digital/include/digital/metric_type.h new file mode 100644 index 000000000..c277f01d2 --- /dev/null +++ b/gr-digital/include/digital/metric_type.h @@ -0,0 +1,37 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 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_METRIC_TYPE_H +#define INCLUDED_DIGITAL_METRIC_TYPE_H + +namespace gr { + namespace digital { + + typedef enum { + TRELLIS_EUCLIDEAN = 200, TRELLIS_HARD_SYMBOL, TRELLIS_HARD_BIT + } trellis_metric_type_t; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_METRIC_TYPE_H */ + diff --git a/gr-digital/include/digital/mpsk_receiver_cc.h b/gr-digital/include/digital/mpsk_receiver_cc.h new file mode 100644 index 000000000..9470cd837 --- /dev/null +++ b/gr-digital/include/digital/mpsk_receiver_cc.h @@ -0,0 +1,146 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,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_MPSK_RECEIVER_CC_H +#define INCLUDED_DIGITAL_MPSK_RECEIVER_CC_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief This block takes care of receiving M-PSK modulated + * signals through phase, frequency, and symbol synchronization. + * \ingroup synchronizers_blk + * + * \details + * This block takes care of receiving M-PSK modulated signals + * through phase, frequency, and symbol synchronization. It + * performs carrier frequency and phase locking as well as symbol + * timing recovery. It works with (D)BPSK, (D)QPSK, and (D)8PSK + * as tested currently. It should also work for OQPSK and PI/4 + * DQPSK. + * + * The phase and frequency synchronization are based on a Costas + * loop that finds the error of the incoming signal point compared + * to its nearest constellation point. The frequency and phase of + * the NCO are updated according to this error. There are + * optimized phase error detectors for BPSK and QPSK, but 8PSK is + * done using a brute-force computation of the constellation + * points to find the minimum. + * + * The symbol synchronization is done using a modified Mueller and + * Muller circuit from the paper: + * + * "G. R. Danesfahani, T. G. Jeans, "Optimisation of modified Mueller + * and Muller algorithm," Electronics Letters, Vol. 31, no. 13, 22 + * June 1995, pp. 1032 - 1033." + * + * This circuit interpolates the downconverted sample (using the + * NCO developed by the Costas loop) every mu samples, then it + * finds the sampling error based on this and the past symbols and + * the decision made on the samples. Like the phase error + * detector, there are optimized decision algorithms for BPSK and + * QPKS, but 8PSK uses another brute force computation against all + * possible symbols. The modifications to the M&M used here reduce + * self-noise. + * + */ + class DIGITAL_API mpsk_receiver_cc : virtual public gr_block + { + public: + // gr::digital::mpsk_receiver_cc::sptr + typedef boost::shared_ptr<mpsk_receiver_cc> sptr; + + /*! + * \brief Buil M-PSK receiver block. + * + * \param M modulation order of the M-PSK modulation + * \param theta any constant phase rotation from the real axis of the constellation + * \param loop_bw Loop bandwidth to set gains of phase/freq tracking loop + * \param fmin minimum normalized frequency value the loop can achieve + * \param fmax maximum normalized frequency value the loop can achieve + * \param mu initial parameter for the interpolator [0,1] + * \param gain_mu gain parameter of the M&M error signal to adjust mu (~0.05) + * \param omega initial value for the number of symbols between samples (~number of samples/symbol) + * \param gain_omega gain parameter to adjust omega based on the error (~omega^2/4) + * \param omega_rel sets the maximum (omega*(1+omega_rel)) and minimum (omega*(1+omega_rel)) omega (~0.005) + * + * The constructor also chooses which phase detector and + * decision maker to use in the work loop based on the value of + * M. + */ + static sptr make(unsigned int M, float theta, + float loop_bw, + float fmin, float fmax, + float mu, float gain_mu, + float omega, float gain_omega, float omega_rel); + + //! Returns the modulation order (M) currently set + virtual float modulation_order() const = 0; + + //! Returns current value of theta + virtual float theta() const = 0; + + //! Returns current value of mu + virtual float mu() const = 0; + + //! Returns current value of omega + virtual float omega() const = 0; + + //! Returns mu gain factor + virtual float gain_mu() const = 0; + + //! Returns omega gain factor + virtual float gain_omega() const = 0; + + //! Returns the relative omega limit + virtual float gain_omega_rel() const = 0; + + //! Sets the modulation order (M) currently + virtual void set_modulation_order(unsigned int M) = 0; + + //! Sets value of theta + virtual void set_theta(float theta) = 0; + + //! Sets value of mu + virtual void set_mu(float mu) = 0; + + //! Sets value of omega and its min and max values + virtual void set_omega(float omega) = 0; + + //! Sets value for mu gain factor + virtual void set_gain_mu(float gain_mu) = 0; + + //! Sets value for omega gain factor + virtual void set_gain_omega(float gain_omega) = 0; + + //! Sets the relative omega limit and resets omega min/max values + virtual void set_gain_omega_rel(float omega_rel) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_MPSK_RECEIVER_CC_H */ diff --git a/gr-digital/include/digital/mpsk_snr_est.h b/gr-digital/include/digital/mpsk_snr_est.h new file mode 100644 index 000000000..f9edcbd05 --- /dev/null +++ b/gr-digital/include/digital/mpsk_snr_est.h @@ -0,0 +1,288 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_MPSK_SNR_EST_H +#define INCLUDED_DIGITAL_MPSK_SNR_EST_H + +#include <digital/api.h> +#include <gr_complex.h> + +namespace gr { + namespace digital { + + /*! + * \brief A block for computing SNR of a signal. + * \ingroup measurement_tools_blk + * + * \details + * Below are some ROUGH estimates of what values of SNR each of + * these types of estimators is good for. In general, these offer + * a trade-off between accuracy and performance. + * + * \li SNR_EST_SIMPLE: Simple estimator (>= 7 dB) + * \li SNR_EST_SKEW: Skewness-base est (>= 5 dB) + * \li SNR_EST_M2M4: 2nd & 4th moment est (>= 1 dB) + * \li SNR_EST_SVR: SVR-based est (>= 0dB) + */ + typedef enum { + SNR_EST_SIMPLE = 0, // Simple estimator (>= 7 dB) + SNR_EST_SKEW, // Skewness-base est (>= 5 dB) + SNR_EST_M2M4, // 2nd & 4th moment est (>= 1 dB) + SNR_EST_SVR // SVR-based est (>= 0dB) + } snr_est_type_t; + + /*! \brief A parent class for SNR estimators, specifically for + * M-PSK signals in AWGN channels. + * \ingroup snr_blk + */ + class DIGITAL_API mpsk_snr_est + { + protected: + double d_alpha, d_beta; + + public: + /*! Constructor + * + * Parameters: + * \param alpha: the update rate of internal running average + * calculations. + */ + mpsk_snr_est(double alpha); + virtual ~mpsk_snr_est(); + + //! Get the running-average coefficient + double alpha() const; + + //! Set the running-average coefficient + void set_alpha(double alpha); + + //! Update the current registers + virtual int update(int noutput_items, + const gr_complex *input); + + //! Use the register values to compute a new estimate + virtual double snr(); + }; + + + //! \brief SNR Estimator using simple mean/variance estimates. + /*! \ingroup snr_blk + * + * A very simple SNR estimator that just uses mean and variance + * estimates of an M-PSK constellation. This esimator is quick + * and cheap and accurate for high SNR (above 7 dB or so) but + * quickly starts to overestimate the SNR at low SNR. + */ + class DIGITAL_API mpsk_snr_est_simple : + public mpsk_snr_est + { + private: + double d_y1, d_y2; + + public: + /*! Constructor + * + * Parameters: + * \param alpha: the update rate of internal running average + * calculations. + */ + mpsk_snr_est_simple(double alpha); + ~mpsk_snr_est_simple() {} + + int update(int noutput_items, + const gr_complex *input); + double snr(); + }; + + + //! \brief SNR Estimator using skewness correction. + /*! \ingroup snr_blk + * + * This is an estimator that came from a discussion between Tom + * Rondeau and fred harris with no known paper reference. The + * idea is that at low SNR, the variance estimations will be + * affected because of fold-over around the decision boundaries, + * which results in a skewness to the samples. We estimate the + * skewness and use this as a correcting term. + */ + class DIGITAL_API mpsk_snr_est_skew : + public mpsk_snr_est + { + private: + double d_y1, d_y2, d_y3; + + public: + /*! Constructor + * + * Parameters: + * \param alpha: the update rate of internal running average + * calculations. + */ + mpsk_snr_est_skew(double alpha); + ~mpsk_snr_est_skew() {} + + int update(int noutput_items, + const gr_complex *input); + double snr(); + }; + + + //! \brief SNR Estimator using 2nd and 4th-order moments. + /*! \ingroup snr_blk + * + * An SNR estimator for M-PSK signals that uses 2nd (M2) and 4th + * (M4) order moments. This estimator uses knowledge of the + * kurtosis of the signal (k_a) and noise (k_w) to make its + * estimation. We use Beaulieu's approximations here to M-PSK + * signals and AWGN channels such that k_a=1 and k_w=2. These + * approximations significantly reduce the complexity of the + * calculations (and computations) required. + * + * Reference: + * D. R. Pauluzzi and N. C. Beaulieu, "A comparison of SNR + * estimation techniques for the AWGN channel," IEEE + * Trans. Communications, Vol. 48, No. 10, pp. 1681-1691, 2000. + */ + class DIGITAL_API mpsk_snr_est_m2m4 : + public mpsk_snr_est + { + private: + double d_y1, d_y2; + + public: + /*! Constructor + * + * Parameters: + * \param alpha: the update rate of internal running average + * calculations. + */ + mpsk_snr_est_m2m4(double alpha); + ~mpsk_snr_est_m2m4() {} + + int update(int noutput_items, + const gr_complex *input); + double snr(); + }; + + + //! \brief SNR Estimator using 2nd and 4th-order moments. + /*! \ingroup snr_blk + * + * An SNR estimator for M-PSK signals that uses 2nd (M2) and 4th + * (M4) order moments. This estimator uses knowledge of the + * kurtosis of the signal (k_a) and noise (k_w) to make its + * estimation. In this case, you can set your own estimations for + * k_a and k_w, the kurtosis of the signal and noise, to fit this + * estimation better to your signal and channel conditions. + * + * A word of warning: this estimator has not been fully tested or + * proved with any amount of rigor. The estimation for M4 in + * particular might be ignoring effectf of when k_a and k_w are + * different. Use this estimator with caution and a copy of the + * reference on hand. + * + * The digital_mpsk_snr_est_m2m4 assumes k_a and k_w to simplify + * the computations for M-PSK and AWGN channels. Use that + * estimator unless you have a way to guess or estimate these + * values here. + * + * Original paper: + * R. Matzner, "An SNR estimation algorithm for complex baseband + * signal using higher order statistics," Facta Universitatis + * (Nis), no. 6, pp. 41-52, 1993. + * + * Reference used in derivation: + * D. R. Pauluzzi and N. C. Beaulieu, "A comparison of SNR + * estimation techniques for the AWGN channel," IEEE + * Trans. Communications, Vol. 48, No. 10, pp. 1681-1691, 2000. + */ + class DIGITAL_API snr_est_m2m4 : + public mpsk_snr_est + { + private: + double d_y1, d_y2; + double d_ka, d_kw; + + public: + /*! Constructor + * + * Parameters: + * \param alpha: the update rate of internal running average + * calculations. + * \param ka: estimate of the signal kurtosis (1 for PSK) + * \param kw: estimate of the channel noise kurtosis (2 for AWGN) + */ + snr_est_m2m4(double alpha, double ka, double kw); + ~snr_est_m2m4() {} + + int update(int noutput_items, + const gr_complex *input); + double snr(); + }; + + + //! \brief Signal-to-Variation Ratio SNR Estimator. + /*! \ingroup snr_blk + * + * This estimator actually comes from an SNR estimator for M-PSK + * signals in fading channels, but this implementation is + * specifically for AWGN channels. The math was simplified to + * assume a signal and noise kurtosis (k_a and k_w) for M-PSK + * signals in AWGN. These approximations significantly reduce the + * complexity of the calculations (and computations) required. + * + * Original paper: + * A. L. Brandao, L. B. Lopes, and D. C. McLernon, "In-service + * monitoring of multipath delay and cochannel interference for + * indoor mobile communication systems," Proc. IEEE + * Int. Conf. Communications, vol. 3, pp. 1458-1462, May 1994. + * + * Reference: + * D. R. Pauluzzi and N. C. Beaulieu, "A comparison of SNR + * estimation techniques for the AWGN channel," IEEE + * Trans. Communications, Vol. 48, No. 10, pp. 1681-1691, 2000. + */ + class DIGITAL_API mpsk_snr_est_svr : + public mpsk_snr_est + { + private: + double d_y1, d_y2; + + public: + /*! Constructor + * + * Parameters: + * \param alpha: the update rate of internal running average + * calculations. + */ + mpsk_snr_est_svr(double alpha); + ~mpsk_snr_est_svr() {} + + int update(int noutput_items, + const gr_complex *input); + double snr(); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_MPSK_SNR_EST_H */ diff --git a/gr-digital/include/digital/mpsk_snr_est_cc.h b/gr-digital/include/digital/mpsk_snr_est_cc.h new file mode 100644 index 000000000..14e8ca3b2 --- /dev/null +++ b/gr-digital/include/digital/mpsk_snr_est_cc.h @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_MPSK_SNR_EST_CC_H +#define INCLUDED_DIGITAL_MPSK_SNR_EST_CC_H + +#include <digital/api.h> +#include <digital/mpsk_snr_est.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief A block for computing SNR of a signal. + * \ingroup measurement_tools_blk + * + * \details + * This block can be used to monitor and retrieve estimations of + * the signal SNR. It is designed to work in a flowgraph and + * passes all incoming data along to its output. + * + * The block is designed for use with M-PSK signals + * especially. The type of estimator is specified as the \p type + * parameter in the constructor. The estimators tend to trade off + * performance for accuracy, although experimentation should be + * done to figure out the right approach for a given + * implementation. Further, the current set of estimators are + * designed and proven theoretically under AWGN conditions; some + * amount of error should be assumed and/or estimated for real + * channel conditions. + */ + class DIGITAL_API mpsk_snr_est_cc : virtual public gr_sync_block + { + public: + // gr::digital::mpsk_snr_est_cc::sptr + typedef boost::shared_ptr<mpsk_snr_est_cc> sptr; + + /*! Factory function returning shared pointer of this class + * + * \param type: the type of estimator to use gr::digital::snr_est_type_t + * "snr_est_type_t" for details about the available types + * \param tag_nsamples: after this many samples, a tag containing + * the SNR (key='snr') will be sent + * \param alpha: the update rate of internal running average + * calculations + */ + static sptr make(snr_est_type_t type, + int tag_nsamples=10000, + double alpha=0.001); + + //! Return the estimated signal-to-noise ratio in decibels + virtual double snr() = 0; + + //! Return the type of estimator in use + virtual snr_est_type_t type() const = 0; + + //! Return how many samples between SNR tags + virtual int tag_nsample() const = 0; + + //! Get the running-average coefficient + virtual double alpha() const = 0; + + //! Set type of estimator to use + virtual void set_type(snr_est_type_t t) = 0; + + //! Set the number of samples between SNR tags + virtual void set_tag_nsample(int n) = 0; + + //! Set the running-average coefficient + virtual void set_alpha(double alpha) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_MPSK_SNR_EST_CC_H */ diff --git a/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h b/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h new file mode 100644 index 000000000..2eaeb7561 --- /dev/null +++ b/gr-digital/include/digital/ofdm_carrier_allocator_cvc.h @@ -0,0 +1,108 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 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_CARRIER_ALLOCATOR_CVC_H +#define INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H + +#include <digital/api.h> +#include <gr_tagged_stream_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Create frequency domain OFDM symbols from complex values, add pilots. + * \ingroup ofdm_blk + * + * \details + * This block turns a stream of complex, scalar modulation symbols into vectors + * which are the input for an IFFT in an OFDM transmitter. It also supports the + * possibility of placing pilot symbols onto the carriers. + * + * The carriers can be allocated freely, if a carrier is not allocated, it is set + * to zero. This allows doing OFDMA-style carrier allocations. + * + * Input: A tagged stream of complex scalars. The first item must have a tag + * containing the number of complex symbols in this frame. + * Output: A tagged stream of complex vectors of length fft_len. This can directly + * be connected to an FFT block. Make sure to set this block to 'reverse' + * for the IFFT. If \p output_is_shifted is true, the FFT block must activate + * FFT shifting, otherwise, set shifting to false. If given, sync words are + * prepended to the output. Note that sync words are prepended verbatim, + * make sure they are shifted (or not). + * + * Carrier indexes are always such that index 0 is the DC carrier (note: you should + * not allocate this carrier). The carriers below the DC carrier are either indexed + * with negative numbers, or with indexes larger than \p fft_len/2. Index -1 and index + * \p fft_len-1 both identify the carrier below the DC carrier. + * + */ + class DIGITAL_API ofdm_carrier_allocator_cvc : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<ofdm_carrier_allocator_cvc> sptr; + + virtual std::string len_tag_key() = 0; + virtual const int fft_len() = 0; + virtual std::vector<std::vector<int> > occupied_carriers() = 0; + + /* + * \param fft_len FFT length, is also the maximum width of the OFDM symbols, the + * output vector size and maximum value for elements in + * \p occupied_carriers and \p pilot_carriers. + * \param occupied_carriers A vector of vectors of indexes. Example: if + * occupied_carriers = ((1, 2, 3), (1, 2, 4)), the first + * three input symbols will be mapped to carriers 1, 2 + * and 3. After that, a new OFDM symbol is started. The next + * three input symbols will be placed onto carriers 1, 2 + * and 4 of the second OFDM symbol. The allocation then + * starts from the beginning. + * Order matters! The first input symbol is always mapped + * onto occupied_carriers[0][0]. + * \param pilot_carriers The position of the pilot symbols. Same as occupied_carriers, + * but the actual symbols are taken from pilot_symbols instead + * of the input stream. + * \param pilot_symbols The pilot symbols which are placed onto the pilot carriers. + * pilot_symbols[0][0] is placed onto the first OFDM symbol, on + * carrier index pilot_carriers[0][0] etc. + * \param sync_words OFDM symbols that are prepended to the OFDM frame (usually for + * synchronisation purposes, e.g. OFDM symbols with every second + * sub-carrier being idle). Is a vector of complex vectors of length + * \p fft_len + * \param len_tag_key The key of the tag identifying the length of the input packet. + */ + static sptr make( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + const std::vector<std::vector<gr_complex> > &sync_words, + const std::string &len_tag_key = "packet_len", + const bool output_is_shifted=true); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_CARRIER_ALLOCATOR_CVC_H */ + diff --git a/gr-digital/include/digital/ofdm_chanest_vcvc.h b/gr-digital/include/digital/ofdm_chanest_vcvc.h new file mode 100644 index 000000000..0607743d5 --- /dev/null +++ b/gr-digital/include/digital/ofdm_chanest_vcvc.h @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 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_CHANEST_VCVC_H +#define INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Estimate channel and coarse frequency offset for OFDM from preambles + * \ingroup ofdm_blk + * \ingroup synchronizers_blk + * + * \details + * Input: OFDM symbols (in frequency domain). The first one (or two) symbols are expected + * to be synchronisation symbols, which are used to estimate the coarse freq offset + * and the initial equalizer taps (these symbols are removed from the stream). + * The following \p n_data_symbols are passed through unmodified (the actual equalisation + * must be done elsewhere). + * Output: The data symbols, without the synchronisation symbols. + * The first data symbol passed through has two tags: + * 'ofdm_sync_carr_offset' (integer), the coarse frequency offset as number of carriers, + * and 'ofdm_sync_eq_taps' (complex vector). + * Any tags attached to the synchronisation symbols are attached to the first data + * symbol. All other tags are propagated normally. + * + * This block assumes the frequency offset is even (i.e. an integer multiple of 2). + * + * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM", + * Communications, IEEE Transactions on, 1997. + * [2] K.D. Kammeyer, "Nachrichtenuebertragung," Chapter. 16.3.2. + */ + class DIGITAL_API ofdm_chanest_vcvc : virtual public gr_block + { + public: + typedef boost::shared_ptr<ofdm_chanest_vcvc> sptr; + + /* + * \param sync_symbol1 First synchronisation symbol in the frequency domain. Its length must be + * the FFT length. For Schmidl & Cox synchronisation, every second sub-carrier + * has to be zero. + * \param sync_symbol2 Second synchronisation symbol in the frequency domain. Must be equal to + * the FFT length, or zero length if only one synchronisation symbol is used. + * Using this symbol is how synchronisation is described in [1]. Leaving this + * empty forces us to interpolate the equalizer taps. + * If you are using an unusual sub-carrier configuration (e.g. because of OFDMA), + * this sync symbol is used to identify the active sub-carriers. If you only + * have one synchronisation symbol, set the active sub-carriers to a non-zero + * value in here, and also set \p force_one_sync_symbol parameter to true. + * \param n_data_symbols The number of data symbols following each set of synchronisation symbols. + * Must be at least 1. + * \param eq_noise_red_len If non-zero, noise reduction for the equalizer taps is done according + * to [2]. In this case, it is the channel influence time in number of + * samples. A good value is usually the length of the cyclic prefix. + * \param max_carr_offset Limit the number of sub-carriers the frequency offset can maximally be. + * Leave this zero to try all possibilities. + * \param force_one_sync_symbol See \p sync_symbol2. + */ + static sptr make( + const std::vector<gr_complex> &sync_symbol1, + const std::vector<gr_complex> &sync_symbol2, + int n_data_symbols, + int eq_noise_red_len=0, + int max_carr_offset=-1, + bool force_one_sync_symbol=false + ); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_CHANEST_VCVC_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 000000000..f8e45edd9 --- /dev/null +++ b/gr-digital/include/digital/ofdm_cyclic_prefixer.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 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_tagged_stream_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Adds a cyclic prefix and performs pulse shaping on OFDM symbols. + * \ingroup ofdm_blk + * + * \details + * Input: OFDM symbols (in the time domain, i.e. after the IFFT). Optionally, + * entire frames can be processed. In this case, \p len_tag_key must be + * specified which holds the key of the tag that denotes how + * many OFDM symbols are in a frame. + * Output: A stream of (scalar) complex symbols, which include the cyclic prefix + * and the pulse shaping. + * Note: If complete frames are processed, and \p rolloff_len is greater + * than zero, the final OFDM symbol is followed by the delay line of + * the pulse shaping. + * + * The pulse shape is a raised cosine in the time domain. + */ + class DIGITAL_API ofdm_cyclic_prefixer : virtual public gr_tagged_stream_block + { + public: + typedef boost::shared_ptr<ofdm_cyclic_prefixer> sptr; + + /*! + * \param input_size FFT length (i.e. length of the OFDM symbols) + * \param output_size FFT length + cyclic prefix length (in samples) + * \param rolloff_len Length of the rolloff flank in samples + * \param len_tag_key For framed processing the key of the length tag + */ + static sptr make( + size_t input_size, + size_t output_size, + int rolloff_len=0, + const std::string &len_tag_key="" + ); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_CYCLIC_PREFIXER_H */ + diff --git a/gr-digital/include/digital/ofdm_equalizer_base.h b/gr-digital/include/digital/ofdm_equalizer_base.h new file mode 100644 index 000000000..4e3a88d58 --- /dev/null +++ b/gr-digital/include/digital/ofdm_equalizer_base.h @@ -0,0 +1,109 @@ +/* -*- c++ -*- */ +/* Copyright 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_EQUALIZER_BASE_H +#define INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H + +#include <digital/api.h> +#include <gr_tags.h> +#include <gr_complex.h> +#include <boost/enable_shared_from_this.hpp> + +namespace gr { + namespace digital { + + /* \brief Base class for implementation details of frequency-domain OFDM equalizers. + * \ingroup ofdm_blk + * \ingroup equalizers_blk + */ + class DIGITAL_API ofdm_equalizer_base + : public boost::enable_shared_from_this<ofdm_equalizer_base> + { + protected: + int d_fft_len; + int d_carr_offset; + + public: + typedef boost::shared_ptr<ofdm_equalizer_base> sptr; + + ofdm_equalizer_base(int fft_len); + virtual ~ofdm_equalizer_base(); + + //! Reset the channel information state knowledge + virtual void reset() = 0; + //! Set the carrier offset in integer multiples + void set_carrier_offset(int offset) { d_carr_offset = offset; }; + virtual void equalize( + gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), + const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()) = 0; + //! Return the current channel state + virtual void get_channel_state(std::vector<gr_complex> &taps) = 0; + int fft_len() { return d_fft_len; }; + sptr base() { return shared_from_this(); }; + }; + + + /* \brief Base class for implementation details of 1-dimensional OFDM FDEs which use pilot tones. + * \ingroup digital + * + */ + class DIGITAL_API ofdm_equalizer_1d_pilots : public ofdm_equalizer_base + { + protected: + //! If \p d_occupied_carriers[k][l] is true, symbol k, carrier l is carrying data. + // (this is a different format than occupied_carriers!) + std::vector<bool> d_occupied_carriers; + //! If \p d_pilot_carriers[k][l] is true, symbol k, carrier l is carrying data. + // (this is a different format than pilot_carriers!) + std::vector<std::vector<bool> > d_pilot_carriers; + //! If \p d_pilot_carriers[k][l] is true, d_pilot_symbols[k][l] is its tx'd value. + // (this is a different format than pilot_symbols!) + std::vector<std::vector<gr_complex> > d_pilot_symbols; + //! In case the frame doesn't begin with OFDM symbol 0, this is the index of the first symbol + int d_symbols_skipped; + //! The current position in the set of pilot symbols + int d_pilot_carr_set; + //! Vector of length d_fft_len saving the current channel state (on the occupied carriers) + std::vector<gr_complex> d_channel_state; + + public: + typedef boost::shared_ptr<ofdm_equalizer_1d_pilots> sptr; + + ofdm_equalizer_1d_pilots( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers, + const std::vector<std::vector<int> > &pilot_carriers, + const std::vector<std::vector<gr_complex> > &pilot_symbols, + int symbols_skipped, + bool input_is_shifted); + ~ofdm_equalizer_1d_pilots(); + + void reset(); + void get_channel_state(std::vector<gr_complex> &taps); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_BASE_H */ + diff --git a/gr-digital/include/digital/ofdm_equalizer_simpledfe.h b/gr-digital/include/digital/ofdm_equalizer_simpledfe.h new file mode 100644 index 000000000..7bf695096 --- /dev/null +++ b/gr-digital/include/digital/ofdm_equalizer_simpledfe.h @@ -0,0 +1,131 @@ +/* -*- c++ -*- */ +/* Copyright 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_EQUALIZER_SIMPLEDFE_H +#define INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H + +#include <digital/api.h> +#include <digital/constellation.h> +#include <digital/ofdm_equalizer_base.h> + +namespace gr { + namespace digital { + + /* \brief Simple decision feedback equalizer for OFDM. + * \ingroup ofdm_blk + * \ingroup equalizers_blk + * + * \details + * Equalizes an OFDM signal symbol by symbol using knowledge of the + * complex modulations symbols. + * For every symbol, the following steps are performed: + * - On every sub-carrier, decode the modulation symbol + * - Use the difference between the decoded symbol and the received symbol + * to update the channel state on this carrier + * - Whenever a pilot symbol is found, it uses the known pilot symbol to + * update the channel state. + * + * This equalizer makes a lot of assumptions: + * - The initial channel state is good enough to decode the first + * symbol without error (unless the first symbol only consists of pilot + * tones) + * - The channel changes only very slowly, such that the channel state + * from one symbol is enough to decode the next + * - SNR low enough that equalization will always suffice to correctly + * decode a symbol + * If these assumptions are not met, the most common error is that the + * channel state is estimated incorrectly during equalization; after that, + * all subsequent symbols will be completely wrong. + * + * Note that the equalized symbols are *exact points* on the constellation. + * This means soft information of the modulation symbols is lost after the + * equalization, which is suboptimal for channel codes that use soft decision. + * + */ + class DIGITAL_API ofdm_equalizer_simpledfe : public ofdm_equalizer_1d_pilots + { + public: + typedef boost::shared_ptr<ofdm_equalizer_simpledfe> sptr; + + ofdm_equalizer_simpledfe( + int fft_len, + const gr::digital::constellation_sptr &constellation, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped = 0, + float alpha = 0.1, + bool input_is_shifted = true); + + ~ofdm_equalizer_simpledfe(); + + void equalize(gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), + const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); + + /* + * \param fft_len FFT length + * \param constellation The constellation object describing the modulation used + * on the subcarriers (e.g. QPSK). This is used to decode + * the individual symbols. + * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator + * for a description. + * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param alpha Averaging coefficient (in a nutshell, if \f$H_{i,k}\f$ is the channel + * state for carrier i and symbol k, + * \f$H_{i,k+1} = \alpha H_{i,k} + (1 - \alpha) H_{i,k+1}\f$. Make this + * larger if there's more noise, but keep in mind that larger values + * of alpha mean slower response to channel changes). + * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers. + * If the first symbol of the frame was removed (e.g. to decode the + * header), set this make sure the pilot symbols are correctly + * identified. + * \param input_is_shifted Set this to false if the input signal is not shifted, i.e. + * the first input items is on the DC carrier. + * Note that a lot of the OFDM receiver blocks operate on shifted + * signals! + */ + static sptr make( + int fft_len, + const gr::digital::constellation_sptr &constellation, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped=0, + float alpha=0.1, + bool input_is_shifted=true + ); + + private: + gr::digital::constellation_sptr d_constellation; + //! Averaging coefficient + float d_alpha; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_SIMPLEDFE_H */ + diff --git a/gr-digital/include/digital/ofdm_equalizer_static.h b/gr-digital/include/digital/ofdm_equalizer_static.h new file mode 100644 index 000000000..6507479f4 --- /dev/null +++ b/gr-digital/include/digital/ofdm_equalizer_static.h @@ -0,0 +1,103 @@ +/* -*- c++ -*- */ +/* Copyright 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_EQUALIZER_STATIC_H +#define INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_H + +#include <digital/api.h> +#include <digital/constellation.h> +#include <digital/ofdm_equalizer_base.h> + +namespace gr { + namespace digital { + + /* \brief Very simple static equalizer for OFDM. + * \ingroup ofdm_blk + * \ingroup equalizers_blk + * + * \details + * This is an extremely simple equalizer. It will only work for + * high-SNR, very, very slowly changing channels. + * + * It simply divides the signal with the currently known channel + * state. Whenever a pilot symbol comes around, it updates the + * channel state on that particular carrier by dividing the + * received symbol with the known pilot symbol. + */ + class DIGITAL_API ofdm_equalizer_static : public ofdm_equalizer_1d_pilots + { + public: + typedef boost::shared_ptr<ofdm_equalizer_static> sptr; + + ofdm_equalizer_static( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped = 0, + bool input_is_shifted = true + ); + ~ofdm_equalizer_static(); + + /*! \brief Divide the input signal with the current channel state. + * + * Does the following (and nothing else): + * - Divide every OFDM symbol with the current channel state + * - If a pilot symbol is found, re-set the channel state by dividing the received + * symbol with the known pilot symbol + */ + void equalize(gr_complex *frame, + int n_sym, + const std::vector<gr_complex> &initial_taps = std::vector<gr_complex>(), + const std::vector<gr_tag_t> &tags = std::vector<gr_tag_t>()); + + /* + * \param fft_len FFT length + * \param occupied_carriers List of occupied carriers, see ofdm_carrier_allocator + * for a description. + * \param pilot_carriers Position of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param pilot_symbols Value of pilot symbols, see ofdm_carrier_allocator + * for a description. + * \param symbols_skipped Starting position within occupied_carriers and pilot_carriers. + * If the first symbol of the frame was removed (e.g. to decode the + * header), set this make sure the pilot symbols are correctly + * identified. + * \param input_is_shifted Set this to false if the input signal is not shifted, i.e. + * the first input items is on the DC carrier. + * Note that a lot of the OFDM receiver blocks operate on shifted + * signals! + */ + static sptr make( + int fft_len, + const std::vector<std::vector<int> > &occupied_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<int> > &pilot_carriers = std::vector<std::vector<int> >(), + const std::vector<std::vector<gr_complex> > &pilot_symbols = std::vector<std::vector<gr_complex> >(), + int symbols_skipped = 0, + bool input_is_shifted = true + ); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_EQUALIZER_STATIC_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 000000000..b8f8ff766 --- /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 ofdm_blk + * + * \details + * 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; + + /*! + * Make 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=4); + + /*! + * \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_equalizer_vcvc.h b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h index 23f3041e2..f8e15fb57 100644 --- a/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h +++ b/gr-digital/include/digital/ofdm_frame_equalizer_vcvc.h @@ -19,12 +19,11 @@ * Boston, MA 02110-1301, USA. */ - #ifndef INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H #define INCLUDED_OFDM_FRAME_EQUALIZER_VCVC_H -#include <digital_ofdm_equalizer_base.h> #include <digital/api.h> +#include <digital/ofdm_equalizer_base.h> #include <gr_tagged_stream_block.h> namespace gr { @@ -34,6 +33,7 @@ namespace gr { * \brief OFDM frame equalizer * \ingroup ofdm_blk * + * \details * Performs equalization in one or two dimensions on a tagged OFDM frame. * Input: a tagged series of OFDM symbols. * Output: The same as the input, but equalized. @@ -50,7 +50,7 @@ namespace gr { * will be added to the first symbol as a tag */ static sptr make( - digital_ofdm_equalizer_base_sptr equalizer, + ofdm_equalizer_base::sptr equalizer, const std::string &len_tag_key = "frame_len", bool propagate_channel_state=false, int fixed_frame_len=0 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 000000000..ff31bad91 --- /dev/null +++ b/gr-digital/include/digital/ofdm_frame_sink.h @@ -0,0 +1,71 @@ +/* -*- 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 ofdm_blk + * + * \details + * 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; + + /*! + * Make an OFDM frame sink block. + * + * \param sym_position vector of OFDM carrier symbols in complex space + * \param sym_value_out vector of bit mapped from the complex symbol space + * \param target_queue message queue for the packets to go into + * \param occupied_tones The number of subcarriers with data in the received symbol + * \param phase_gain gain of the phase tracking loop + * \param freq_gain gain of the frequency tracking loop + */ + static sptr make(const std::vector<gr_complex> &sym_position, + const std::vector<char> &sym_value_out, + gr_msg_queue_sptr target_queue, + int occupied_tones, + float phase_gain=0.25, float freq_gain=0.25*0.25/4); + }; + + } /* 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 000000000..a9ad61e1d --- /dev/null +++ b/gr-digital/include/digital/ofdm_insert_preamble.h @@ -0,0 +1,79 @@ +/* -*- 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 ofdm_blk + * \ingroup synchronizers_blk + * + * \details + * <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> + */ + 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; + + /*! + * Make an OFDM preamble inserter block. + * + * \param fft_length length of each symbol in samples. + * \param preamble vector of symbols that represent the pre-modulated preamble. + */ + 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 000000000..49ae9adc9 --- /dev/null +++ b/gr-digital/include/digital/ofdm_mapper_bcv.h @@ -0,0 +1,67 @@ +/* -*- 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. + * \ingroup ofdm_blk + * + * \details + * Abstract class must be subclassed with specific mapping. + */ + 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; + + /*! + * Make an OFDM mapper block. + * + * \param constellation vector of OFDM carrier symbols in complex space + * \param msgq_limit limit on number of messages the queue can store + * \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) + */ + 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/include/digital/ofdm_sampler.h b/gr-digital/include/digital/ofdm_sampler.h new file mode 100644 index 000000000..5df16be3e --- /dev/null +++ b/gr-digital/include/digital/ofdm_sampler.h @@ -0,0 +1,57 @@ +/* -*- 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_H +#define INCLUDED_DIGITAL_OFDM_SAMPLER_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +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; + + /*! + * Make an OFDM sampler block. + * + * \param fft_length The size of the FFT vector (occupied_carriers + unused carriers) + * \param symbol_length Length of the full symbol (fft_length + CP length) + * \param timeout timeout in samples when we stop looking for a symbol after initial ack. + */ + static sptr make(unsigned int fft_length, + unsigned int symbol_length, + unsigned int timeout=1000); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_OFDM_SAMPLER_H */ diff --git a/gr-digital/include/digital/ofdm_serializer_vcc.h b/gr-digital/include/digital/ofdm_serializer_vcc.h index 3893d6674..f02b0f85b 100644 --- a/gr-digital/include/digital/ofdm_serializer_vcc.h +++ b/gr-digital/include/digital/ofdm_serializer_vcc.h @@ -24,7 +24,7 @@ #include <digital/api.h> #include <gr_tagged_stream_block.h> -#include <digital_ofdm_carrier_allocator_cvc.h> +#include <digital/ofdm_carrier_allocator_cvc.h> namespace gr { namespace digital { @@ -33,6 +33,7 @@ namespace gr { * \brief Serializes complex modulations symbols from OFDM sub-carriers * \ingroup ofdm_blk * + * \details * This is the inverse block to the carrier_allocator_cvc. It outputs the * complex data symbols as a tagged stream, discarding the pilot symbols. * @@ -77,7 +78,7 @@ namespace gr { * \param input_is_shifted If the input has the DC carrier on index 0 (i.e. it is not FFT shifted), set this to false */ static sptr make( - const digital_ofdm_carrier_allocator_cvc_sptr &allocator, + const gr::digital::ofdm_carrier_allocator_cvc::sptr &allocator, const std::string &packet_len_tag_key="", int symbols_skipped=0, bool input_is_shifted=true diff --git a/gr-digital/include/digital/ofdm_sync_sc_cfb.h b/gr-digital/include/digital/ofdm_sync_sc_cfb.h new file mode 100644 index 000000000..84f3e704a --- /dev/null +++ b/gr-digital/include/digital/ofdm_sync_sc_cfb.h @@ -0,0 +1,79 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 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_SYNC_SC_CFB_H +#define INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H + +#include <digital/api.h> +#include <gr_hier_block2.h> + +namespace gr { + namespace digital { + + /*! + * \brief Schmidl & Cox synchronisation for OFDM + * \ingroup ofdm_blk + * \ingroup synchronizers_blk + * + * \details + * Input: complex samples. + * Output 0: Fine frequency offset, scaled by the OFDM symbol duration. + * This is \f$\hat{\varphi}\f$ in [1]. The normalized frequency + * offset is then 2.0*output0/fft_len. + * Output 1: Beginning of the first OFDM symbol after the first (doubled) OFDM + * symbol. The beginning is marked with a 1 (it's 0 everywhere else). + * + * The evaluation of the coarse frequency offset is *not* done in this block. + * Also, the initial equalizer taps are not calculated here. + * + * Note that we use a different normalization factor in the timing metric than + * the authors do in their original work[1]. If the timing metric (8) is + * \f[ + * M(d) = \frac{|P(d)|^2}{(R(d))^2}, + * \f] + * we calculate the normalization as + * \f[ + * R(d) = \frac{1}{2} \sum_{k=0}^{N-1} |r_{k+d}|^2, + * \f] + * i.e., we estimate the energy from *both* half-symbols. This avoids spurious detects + * at the end of a burst, when the energy level suddenly drops. + * + * [1] Schmidl, T.M. and Cox, D.C., "Robust frequency and timing synchronization for OFDM", + * Communications, IEEE Transactions on, 1997. + */ + class DIGITAL_API ofdm_sync_sc_cfb : virtual public gr_hier_block2 + { + public: + typedef boost::shared_ptr<ofdm_sync_sc_cfb> sptr; + + /*! \param fft_len FFT length + * \param cp_len Length of the guard interval (cyclic prefix) in samples + */ + static sptr make(int fft_len, int cp_len); + }; + + } // namespace digital +} // namespace gr + +#endif /* INCLUDED_DIGITAL_OFDM_SYNC_SC_CFB_H */ + diff --git a/gr-digital/include/digital/packet_header_ofdm.h b/gr-digital/include/digital/packet_header_ofdm.h index de4f0a500..30d6a953c 100644 --- a/gr-digital/include/digital/packet_header_ofdm.h +++ b/gr-digital/include/digital/packet_header_ofdm.h @@ -32,7 +32,6 @@ namespace gr { /*! * \brief Header utility for OFDM signals. * \ingroup ofdm_blk - * */ class DIGITAL_API packet_header_ofdm : public packet_header_default { diff --git a/gr-digital/include/digital/packet_sink.h b/gr-digital/include/digital/packet_sink.h new file mode 100644 index 000000000..42f826535 --- /dev/null +++ b/gr-digital/include/digital/packet_sink.h @@ -0,0 +1,80 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,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_GR_PACKET_SINK_H +#define INCLUDED_GR_PACKET_SINK_H + +#include <digital/api.h> +#include <gr_sync_block.h> +#include <gr_msg_queue.h> + +namespace gr { + namespace digital { + + /*! + * \brief process received bits looking for packet sync, header, + * and process bits into packet + * \ingroup packet_operators_blk + * + * \details + * input: stream of symbols to be sliced. + * + * output: none. Pushes assembled packet into target queue + * + * The packet sink takes in a stream of binary symbols that are + * sliced around 0. The bits are then checked for the \p + * sync_vector to determine find and decode the packet. It then + * expects a fixed length header of 2 16-bit shorts containing the + * payload length, followed by the payload. If the 2 16-bit shorts + * are not identical, this packet is ignored. Better algs are + * welcome. + * + * This block is not very useful anymore as it only works with + * 2-level modulations such as BPSK or GMSK. The block can + * generally be replaced with a correlate access code and frame + * sink blocks. + */ + class DIGITAL_API packet_sink : virtual public gr_sync_block + { + public: + // gr::digital::packet_sink::sptr + typedef boost::shared_ptr<packet_sink> sptr; + + /*! + * Make a packet_sink block. + * + * \param sync_vector The synchronization vector as a vector of 1's and 0's. + * \param target_queue The message queue that packets are sent to. + * \param threshold Number of bits that can be incorrect in the \p sync_vector. + */ + static sptr make(const std::vector<unsigned char>& sync_vector, + gr_msg_queue_sptr target_queue, + int threshold=-1); + + //! return true if we detect carrier + virtual bool carrier_sensed() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_PACKET_SINK_H */ diff --git a/gr-digital/include/digital/pfb_clock_sync_ccf.h b/gr-digital/include/digital/pfb_clock_sync_ccf.h new file mode 100644 index 000000000..2cdb55ca4 --- /dev/null +++ b/gr-digital/include/digital/pfb_clock_sync_ccf.h @@ -0,0 +1,330 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,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. + */ + + +#ifndef INCLUDED_DIGITAL_PFB_CLOCK_SYNC_CCF_H +#define INCLUDED_DIGITAL_PFB_CLOCK_SYNC_CCF_H + +#include <digital/api.h> +#include <filter/fir_filter.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Timing synchronizer using polyphase filterbanks + * \ingroup synchronizers_blk + * + * \details + * This block performs timing synchronization for PAM signals by + * minimizing the derivative of the filtered signal, which in turn + * maximizes the SNR and minimizes ISI. + * + * This approach works by setting up two filterbanks; one + * filterbank contains the signal's pulse shaping matched filter + * (such as a root raised cosine filter), where each branch of the + * filterbank contains a different phase of the filter. The + * second filterbank contains the derivatives of the filters in + * the first filterbank. Thinking of this in the time domain, the + * first filterbank contains filters that have a sinc shape to + * them. We want to align the output signal to be sampled at + * exactly the peak of the sinc shape. The derivative of the sinc + * contains a zero at the maximum point of the sinc (sinc(0) = 1, + * sinc(0)' = 0). Furthermore, the region around the zero point + * is relatively linear. We make use of this fact to generate the + * error signal. + * + * If the signal out of the derivative filters is d_i[n] for the + * ith filter, and the output of the matched filter is x_i[n], we + * calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} + + * Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error + * in the real and imaginary parts. There are two reasons we + * multiply by the signal itself. First, if the symbol could be + * positive or negative going, but we want the error term to + * always tell us to go in the same direction depending on which + * side of the zero point we are on. The sign of x_i[n] adjusts + * the error term to do this. Second, the magnitude of x_i[n] + * scales the error term depending on the symbol's amplitude, so + * larger signals give us a stronger error term because we have + * more confidence in that symbol's value. Using the magnitude of + * x_i[n] instead of just the sign is especially good for signals + * with low SNR. + * + * The error signal, e[n], gives us a value proportional to how + * far away from the zero point we are in the derivative + * signal. We want to drive this value to zero, so we set up a + * second order loop. We have two variables for this loop; d_k is + * the filter number in the filterbank we are on and d_rate is the + * rate which we travel through the filters in the steady + * state. That is, due to the natural clock differences between + * the transmitter and receiver, d_rate represents that difference + * and would traverse the filter phase paths to keep the receiver + * locked. Thinking of this as a second-order PLL, the d_rate is + * the frequency and d_k is the phase. So we update d_rate and d_k + * using the standard loop equations based on two error signals, + * d_alpha and d_beta. We have these two values set based on each + * other for a critically damped system, so in the block + * constructor, we just ask for "gain," which is d_alpha while + * d_beta is equal to (gain^2)/4. + * + * The block's parameters are: + * + * \li \p sps: The clock sync block needs to know the number of + * samples per symbol, because it defaults to return a single + * point representing the symbol. The sps can be any positive real + * number and does not need to be an integer. + * + * \li \p loop_bw: The loop bandwidth is used to set the gain of + * the inner control loop (see: + * http://gnuradio.squarespace.com/blog/2011/8/13/control-loop-gain-values.html). + * This should be set small (a value of around 2pi/100 is + * suggested in that blog post as the step size for the number of + * radians around the unit circle to move relative to the error). + * + * \li \p taps: One of the most important parameters for this + * block is the taps of the filter. One of the benefits of this + * algorithm is that you can put the matched filter in here as the + * taps, so you get both the matched filter and sample timing + * correction in one go. So create your normal matched filter. For + * a typical digital modulation, this is a root raised cosine + * filter. The number of taps of this filter is based on how long + * you expect the channel to be; that is, how many symbols do you + * want to combine to get the current symbols energy back (there's + * probably a better way of stating that). It's usually 5 to 10 or + * so. That gives you your filter, but now we need to think about + * it as a filter with different phase profiles in each filter. So + * take this number of taps and multiply it by the number of + * filters. This is the number you would use to create your + * prototype filter. When you use this in the PFB filerbank, it + * segments these taps into the filterbanks in such a way that + * each bank now represents the filter at different phases, + * equally spaced at 2pi/N, where N is the number of filters. + * + * \li \p filter_size (default=32): The number of filters can also + * be set and defaults to 32. With 32 filters, you get a good + * enough resolution in the phase to produce very small, almost + * unnoticeable, ISI. Going to 64 filters can reduce this more, + * but after that there is very little gained for the extra + * complexity. + * + * \li \p init_phase (default=0): The initial phase is another + * settable parameter and refers to the filter path the algorithm + * initially looks at (i.e., d_k starts at init_phase). This value + * defaults to zero, but it might be useful to start at a + * different phase offset, such as the mid-point of the filters. + * + * \li \p max_rate_deviation (default=1.5): The next parameter is + * the max_rate_devitation, which defaults to 1.5. This is how far + * we allow d_rate to swing, positive or negative, from + * 0. Constraining the rate can help keep the algorithm from + * walking too far away to lock during times when there is no + * signal. + * + * \li \p osps (default=1): The osps is the number of output + * samples per symbol. By default, the algorithm produces 1 sample + * per symbol, sampled at the exact sample value. This osps value + * was added to better work with equalizers, which do a better job + * of modeling the channel if they have 2 samps/sym. + */ + class DIGITAL_API pfb_clock_sync_ccf : virtual public gr_block + { + public: + // gr::digital::pfb_clock_sync_ccf::sptr + typedef boost::shared_ptr<pfb_clock_sync_ccf> sptr; + + /*! + * Build the polyphase filterbank timing synchronizer. + * \param sps (double) The number of samples per symbol in the incoming signal + * \param loop_bw (float) The bandwidth of the control loop; set's alpha and beta. + * \param taps (vector<int>) The filter taps. + * \param filter_size (uint) The number of filters in the filterbank (default = 32). + * \param init_phase (float) The initial phase to look at, or which filter to start + * with (default = 0). + * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5). + * \param osps (int) The number of output samples per symbol (default=1). + */ + static sptr make(double sps, float loop_bw, + const std::vector<float> &taps, + unsigned int filter_size=32, + float init_phase=0, + float max_rate_deviation=1.5, + int osps=1); + + /*! \brief update the system gains from omega and eta + * + * This function updates the system gains based on the loop + * bandwidth and damping factor of the system. + * These two factors can be set separately through their own + * set functions. + */ + virtual void update_gains() = 0; + + /*! + * Resets the filterbank's filter taps with the new prototype filter + */ + virtual void set_taps(const std::vector<float> &taps, + std::vector< std::vector<float> > &ourtaps, + std::vector<gr::filter::kernel::fir_filter_ccf*> &ourfilter) = 0; + + /*! + * Returns all of the taps of the matched filter + */ + virtual std::vector< std::vector<float> > taps() const = 0; + + /*! + * Returns all of the taps of the derivative filter + */ + virtual std::vector< std::vector<float> > diff_taps() const = 0; + + /*! + * Returns the taps of the matched filter for a particular channel + */ + virtual std::vector<float> channel_taps(int channel) const = 0; + + /*! + * Returns the taps in the derivative filter for a particular channel + */ + virtual std::vector<float> diff_channel_taps(int channel) const = 0; + + /*! + * Return the taps as a formatted string for printing + */ + virtual std::string taps_as_string() const = 0; + + /*! + * Return the derivative filter taps as a formatted string for printing + */ + virtual std::string diff_taps_as_string() const = 0; + + + /******************************************************************* + SET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Set the loop bandwidth + * + * Set the loop filter's bandwidth to \p bw. This should be + * between 2*pi/200 and 2*pi/100 (in rads/samp). It must also be + * a positive number. + * + * When a new damping factor is set, the gains, alpha and beta, + * of the loop are recalculated by a call to update_gains(). + * + * \param bw (float) new bandwidth + */ + virtual void set_loop_bandwidth(float bw) = 0; + + /*! + * \brief Set the loop damping factor + * + * Set the loop filter's damping factor to \p df. The damping + * factor should be sqrt(2)/2.0 for critically damped systems. + * Set it to anything else only if you know what you are + * doing. It must be a number between 0 and 1. + * + * When a new damping factor is set, the gains, alpha and beta, + * of the loop are recalculated by a call to update_gains(). + * + * \param df (float) new damping factor + */ + virtual void set_damping_factor(float df) = 0; + + /*! + * \brief Set the loop gain alpha + * + * Set's the loop filter's alpha gain parameter. + * + * This value should really only be set by adjusting the loop + * bandwidth and damping factor. + * + * \param alpha (float) new alpha gain + */ + virtual void set_alpha(float alpha) = 0; + + /*! + * \brief Set the loop gain beta + * + * Set's the loop filter's beta gain parameter. + * + * This value should really only be set by adjusting the loop + * bandwidth and damping factor. + * + * \param beta (float) new beta gain + */ + virtual void set_beta(float beta) = 0; + + /*! + * Set the maximum deviation from 0 d_rate can have + */ + virtual void set_max_rate_deviation(float m) = 0; + + /******************************************************************* + GET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Returns the loop bandwidth + */ + virtual float loop_bandwidth() const = 0; + + /*! + * \brief Returns the loop damping factor + */ + virtual float damping_factor() const = 0; + + /*! + * \brief Returns the loop gain alpha + */ + virtual float alpha() const = 0; + + /*! + * \brief Returns the loop gain beta + */ + virtual float beta() const = 0; + + /*! + * \brief Returns the current clock rate + */ + virtual float clock_rate() const = 0; + + /*! + * \brief Returns the current error of the control loop. + */ + virtual float error() const = 0; + + /*! + * \brief Returns the current rate of the control loop. + */ + virtual float rate() const = 0; + + /*! + * \brief Returns the current phase arm of the control loop. + */ + virtual float phase() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_PFB_CLOCK_SYNC_CCF_H */ diff --git a/gr-digital/include/digital/pfb_clock_sync_fff.h b/gr-digital/include/digital/pfb_clock_sync_fff.h new file mode 100644 index 000000000..f0fc6df31 --- /dev/null +++ b/gr-digital/include/digital/pfb_clock_sync_fff.h @@ -0,0 +1,316 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,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. + */ + +#ifndef INCLUDED_DIGITAL_PFB_CLOCK_SYNC_FFF_H +#define INCLUDED_DIGITAL_PFB_CLOCK_SYNC_FFF_H + +#include <digital/api.h> +#include <filter/fir_filter.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Timing synchronizer using polyphase filterbanks + * \ingroup synchronizers_blk + * + * \details + * This block performs timing synchronization for PAM signals by + * minimizing the derivative of the filtered signal, which in turn + * maximizes the SNR and minimizes ISI. + * + * This approach works by setting up two filterbanks; one + * filterbank contains the signal's pulse shaping matched filter + * (such as a root raised cosine filter), where each branch of the + * filterbank contains a different phase of the filter. The + * second filterbank contains the derivatives of the filters in + * the first filterbank. Thinking of this in the time domain, the + * first filterbank contains filters that have a sinc shape to + * them. We want to align the output signal to be sampled at + * exactly the peak of the sinc shape. The derivative of the sinc + * contains a zero at the maximum point of the sinc (sinc(0) = 1, + * sinc(0)' = 0). Furthermore, the region around the zero point + * is relatively linear. We make use of this fact to generate the + * error signal. + * + * If the signal out of the derivative filters is d_i[n] for the + * ith filter, and the output of the matched filter is x_i[n], we + * calculate the error as: e[n] = (Re{x_i[n]} * Re{d_i[n]} + + * Im{x_i[n]} * Im{d_i[n]}) / 2.0 This equation averages the error + * in the real and imaginary parts. There are two reasons we + * multiply by the signal itself. First, if the symbol could be + * positive or negative going, but we want the error term to + * always tell us to go in the same direction depending on which + * side of the zero point we are on. The sign of x_i[n] adjusts + * the error term to do this. Second, the magnitude of x_i[n] + * scales the error term depending on the symbol's amplitude, so + * larger signals give us a stronger error term because we have + * more confidence in that symbol's value. Using the magnitude of + * x_i[n] instead of just the sign is especially good for signals + * with low SNR. + * + * The error signal, e[n], gives us a value proportional to how + * far away from the zero point we are in the derivative + * signal. We want to drive this value to zero, so we set up a + * second order loop. We have two variables for this loop; d_k is + * the filter number in the filterbank we are on and d_rate is the + * rate which we travel through the filters in the steady + * state. That is, due to the natural clock differences between + * the transmitter and receiver, d_rate represents that difference + * and would traverse the filter phase paths to keep the receiver + * locked. Thinking of this as a second-order PLL, the d_rate is + * the frequency and d_k is the phase. So we update d_rate and d_k + * using the standard loop equations based on two error signals, + * d_alpha and d_beta. We have these two values set based on each + * other for a critically damped system, so in the block + * constructor, we just ask for "gain," which is d_alpha while + * d_beta is equal to (gain^2)/4. + * + * The block's parameters are: + * + * \li \p sps: The clock sync block needs to know the number of + * samples per symbol, because it defaults to return a single + * point representing the symbol. The sps can be any positive real + * number and does not need to be an integer. + * + * \li \p loop_bw: The loop bandwidth is used to set the gain of + * the inner control loop (see: + * http://gnuradio.squarespace.com/blog/2011/8/13/control-loop-gain-values.html). + * This should be set small (a value of around 2pi/100 is + * suggested in that blog post as the step size for the number of + * radians around the unit circle to move relative to the error). + * + * \li \p taps: One of the most important parameters for this + * block is the taps of the filter. One of the benefits of this + * algorithm is that you can put the matched filter in here as the + * taps, so you get both the matched filter and sample timing + * correction in one go. So create your normal matched filter. For + * a typical digital modulation, this is a root raised cosine + * filter. The number of taps of this filter is based on how long + * you expect the channel to be; that is, how many symbols do you + * want to combine to get the current symbols energy back (there's + * probably a better way of stating that). It's usually 5 to 10 or + * so. That gives you your filter, but now we need to think about + * it as a filter with different phase profiles in each filter. So + * take this number of taps and multiply it by the number of + * filters. This is the number you would use to create your + * prototype filter. When you use this in the PFB filerbank, it + * segments these taps into the filterbanks in such a way that + * each bank now represents the filter at different phases, + * equally spaced at 2pi/N, where N is the number of filters. + * + * \li \p filter_size (default=32): The number of filters can also + * be set and defaults to 32. With 32 filters, you get a good + * enough resolution in the phase to produce very small, almost + * unnoticeable, ISI. Going to 64 filters can reduce this more, + * but after that there is very little gained for the extra + * complexity. + * + * \li \p init_phase (default=0): The initial phase is another + * settable parameter and refers to the filter path the algorithm + * initially looks at (i.e., d_k starts at init_phase). This value + * defaults to zero, but it might be useful to start at a + * different phase offset, such as the mid-point of the filters. + * + * \li \p max_rate_deviation (default=1.5): The next parameter is + * the max_rate_devitation, which defaults to 1.5. This is how far + * we allow d_rate to swing, positive or negative, from + * 0. Constraining the rate can help keep the algorithm from + * walking too far away to lock during times when there is no + * signal. + * + * \li \p osps (default=1): The osps is the number of output + * samples per symbol. By default, the algorithm produces 1 sample + * per symbol, sampled at the exact sample value. This osps value + * was added to better work with equalizers, which do a better job + * of modeling the channel if they have 2 samps/sym. + */ + class DIGITAL_API pfb_clock_sync_fff : virtual public gr_block + { + public: + // gr::digital::pfb_clock_sync_fff::sptr + typedef boost::shared_ptr<pfb_clock_sync_fff> sptr; + + /*! + * Build the polyphase filterbank timing synchronizer. + * \param sps (double) The number of samples per second in the incoming signal + * \param gain (float) The alpha gain of the control loop; beta = (gain^2)/4 by default. + * \param taps (vector<int>) The filter taps. + * \param filter_size (uint) The number of filters in the filterbank (default = 32). + * \param init_phase (float) The initial phase to look at, or which filter to start + * with (default = 0). + * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5). + * \param osps (int) The number of output samples per symbol (default=1). + * + */ + static sptr make(double sps, float gain, + const std::vector<float> &taps, + unsigned int filter_size=32, + float init_phase=0, + float max_rate_deviation=1.5, + int osps=1); + + /*! \brief update the system gains from omega and eta + * + * This function updates the system gains based on the loop + * bandwidth and damping factor of the system. + * These two factors can be set separately through their own + * set functions. + */ + virtual void update_gains() = 0; + + /*! + * Resets the filterbank's filter taps with the new prototype filter + */ + virtual void set_taps(const std::vector<float> &taps, + std::vector< std::vector<float> > &ourtaps, + std::vector<gr::filter::kernel::fir_filter_fff*> &ourfilter) = 0; + + /*! + * Returns all of the taps of the matched filter + */ + virtual std::vector< std::vector<float> > taps() const = 0; + + /*! + * Returns all of the taps of the derivative filter + */ + virtual std::vector< std::vector<float> > diff_taps() const = 0; + + /*! + * Returns the taps of the matched filter for a particular channel + */ + virtual std::vector<float> channel_taps(int channel) const = 0; + + /*! + * Returns the taps in the derivative filter for a particular channel + */ + virtual std::vector<float> diff_channel_taps(int channel) const = 0; + + /*! + * Return the taps as a formatted string for printing + */ + virtual std::string taps_as_string() const = 0; + + /*! + * Return the derivative filter taps as a formatted string for printing + */ + virtual std::string diff_taps_as_string() const = 0; + + + /******************************************************************* + SET FUNCTIONS + *******************************************************************/ + + + /*! + * \brief Set the loop bandwidth + * + * Set the loop filter's bandwidth to \p bw. This should be + * between 2*pi/200 and 2*pi/100 (in rads/samp). It must also be + * a positive number. + * + * When a new damping factor is set, the gains, alpha and beta, + * of the loop are recalculated by a call to update_gains(). + * + * \param bw (float) new bandwidth + */ + virtual void set_loop_bandwidth(float bw) = 0; + + /*! + * \brief Set the loop damping factor + * + * Set the loop filter's damping factor to \p df. The damping + * factor should be sqrt(2)/2.0 for critically damped systems. + * Set it to anything else only if you know what you are + * doing. It must be a number between 0 and 1. + * + * When a new damping factor is set, the gains, alpha and beta, + * of the loop are recalculated by a call to update_gains(). + * + * \param df (float) new damping factor + */ + virtual void set_damping_factor(float df) = 0; + + /*! + * \brief Set the loop gain alpha + * + * Set's the loop filter's alpha gain parameter. + * + * This value should really only be set by adjusting the loop + * bandwidth and damping factor. + * + * \param alpha (float) new alpha gain + */ + virtual void set_alpha(float alpha) = 0; + + /*! + * \brief Set the loop gain beta + * + * Set's the loop filter's beta gain parameter. + * + * This value should really only be set by adjusting the loop + * bandwidth and damping factor. + * + * \param beta (float) new beta gain + */ + virtual void set_beta(float beta) = 0; + + /*! + * Set the maximum deviation from 0 d_rate can have + */ + virtual void set_max_rate_deviation(float m) = 0; + + /******************************************************************* + GET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Returns the loop bandwidth + */ + virtual float loop_bandwidth() const = 0; + + /*! + * \brief Returns the loop damping factor + */ + virtual float damping_factor() const = 0; + + /*! + * \brief Returns the loop gain alpha + */ + virtual float alpha() const = 0; + + /*! + * \brief Returns the loop gain beta + */ + virtual float beta() const = 0; + + /*! + * \brief Returns the current clock rate + */ + virtual float clock_rate() const = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_PFB_CLOCK_SYNC_FFF_H */ diff --git a/gr-digital/include/digital/pn_correlator_cc.h b/gr-digital/include/digital/pn_correlator_cc.h new file mode 100644 index 000000000..147983f89 --- /dev/null +++ b/gr-digital/include/digital/pn_correlator_cc.h @@ -0,0 +1,63 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,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_GR_PN_CORRELATOR_CC_H +#define INCLUDED_GR_PN_CORRELATOR_CC_H + +#include <digital/api.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace digital { + + /*! + * \brief PN code sequential search correlator + * \ingroup synchronizers_blk + * + * \details + * Receives complex baseband signal, outputs complex correlation + * against reference PN code, one sample per PN code period. The + * PN sequence is generated using a GLFSR. + */ + class DIGITAL_API pn_correlator_cc : virtual public gr_sync_decimator + { + public: + // gr::digital::pn_correlator_cc::sptr + typedef boost::shared_ptr<pn_correlator_cc> sptr; + + /*! + * \brief Make PN code sequential search correlator block. + * + * \param degree Degree of shift register must be in [1, 32]. If mask + * is 0, the degree determines a default mask (see + * digital_impl_glfsr.cc for the mapping). + * \param mask Allows a user-defined bit mask for indexes of the shift + * register to feed back. + * \param seed Initial setting for values in shift register. + */ + static sptr make(int degree, int mask=0, int seed=1); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_PN_CORRELATOR_CC_H */ diff --git a/gr-digital/include/digital/probe_density_b.h b/gr-digital/include/digital/probe_density_b.h new file mode 100644 index 000000000..b0343d2cf --- /dev/null +++ b/gr-digital/include/digital/probe_density_b.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2012 Free Software Foundation, Inc. + * + * 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_GR_PROBE_DENSITY_B_H +#define INCLUDED_GR_PROBE_DENSITY_B_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \ingroup measurement_tools_blk + * + * This block maintains a running average of the input stream and + * makes it available as an accessor function. The input stream is + * type unsigned char. + * + * If you send this block a stream of unpacked bytes, it will tell + * you what the bit density is. + */ + class DIGITAL_API probe_density_b : virtual public gr_sync_block + { + public: + // gr::digital::probe_density_b::sptr + typedef boost::shared_ptr<probe_density_b> sptr; + + /*! + * Make a density probe block. + * + * \param alpha Average filter constant + * + */ + static sptr make(double alpha); + + /*! + * \brief Returns the current density value + */ + virtual double density() const = 0; + + /*! + * \brief Set the average filter constant + */ + virtual void set_alpha(double alpha) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_PROBE_DENSITY_B_H */ diff --git a/gr-digital/include/digital/probe_mpsk_snr_est_c.h b/gr-digital/include/digital/probe_mpsk_snr_est_c.h new file mode 100644 index 000000000..289940cdd --- /dev/null +++ b/gr-digital/include/digital/probe_mpsk_snr_est_c.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 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_PROBE_MPSK_SNR_EST_C_H +#define INCLUDED_DIGITAL_PROBE_MPSK_SNR_EST_C_H + +#include <digital/api.h> +#include <digital/mpsk_snr_est.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief A probe for computing SNR of a signal. + * \ingroup measurement_tools_blk + * + * \details + * This is a probe block (a sink) that can be used to monitor and + * retrieve estimations of the signal SNR. This probe is designed + * for use with M-PSK signals especially. The type of estimator is + * specified as the \p type parameter in the constructor. The + * estimators tend to trade off performance for accuracy, although + * experimentation should be done to figure out the right approach + * for a given implementation. Further, the current set of + * estimators are designed and proven theoretically under AWGN + * conditions; some amount of error should be assumed and/or + * estimated for real channel conditions. + */ + class DIGITAL_API probe_mpsk_snr_est_c : virtual public gr_sync_block + { + public: + // gr::digital::probe_mpsk_snr_est_c::sptr + typedef boost::shared_ptr<probe_mpsk_snr_est_c> sptr; + + /*! Make an MPSK SNR probe. + * + * Parameters: + * + * \param type: the type of estimator to use see + * gr::digital::snr_est_type_t for details about the types. + * \param msg_nsamples: [not implemented yet] after this many + * samples, a message containing the SNR (key='snr') will be sent + * \param alpha: the update rate of internal running average + * calculations. + */ + static sptr make(snr_est_type_t type, + int msg_nsamples=10000, + double alpha=0.001); + + //! Return the estimated signal-to-noise ratio in decibels + virtual double snr() = 0; + + //! Return the type of estimator in use + virtual snr_est_type_t type() const = 0; + + //! Return how many samples between SNR messages + virtual int msg_nsample() const = 0; + + //! Get the running-average coefficient + virtual double alpha() const = 0; + + //! Set type of estimator to use + virtual void set_type(snr_est_type_t t) = 0; + + //! Set the number of samples between SNR messages + virtual void set_msg_nsample(int n) = 0; + + //! Set the running-average coefficient + virtual void set_alpha(double alpha) = 0; + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_PROBE_MPSK_SNR_EST_C_H */ diff --git a/gr-digital/include/digital/scrambler_bb.h b/gr-digital/include/digital/scrambler_bb.h new file mode 100644 index 000000000..6360662da --- /dev/null +++ b/gr-digital/include/digital/scrambler_bb.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,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_GR_SCRAMBLER_BB_H +#define INCLUDED_GR_SCRAMBLER_BB_H + +#include <digital/api.h> +#include <gr_sync_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief Scramble an input stream using an LFSR. + * \ingroup coding_blk + * + * \details + * This block works on the LSB only of the input data stream, + * i.e., on an "unpacked binary" stream, and produces the same + * format on its output. + */ + class DIGITAL_API scrambler_bb : virtual public gr_sync_block + { + public: + // gr::digital::scrambler_bb::sptr + typedef boost::shared_ptr<scrambler_bb> sptr; + + /*! + * Make a scramber block. + * + * \param mask Polynomial mask for LFSR + * \param seed Initial shift register contents + * \param len Shift register length + */ + static sptr make(int mask, int seed, int len); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_SCRAMBLER_BB_H */ diff --git a/gr-digital/include/digital/simple_correlator.h b/gr-digital/include/digital/simple_correlator.h new file mode 100644 index 000000000..5cb7ddc6e --- /dev/null +++ b/gr-digital/include/digital/simple_correlator.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2013 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_GR_SIMPLE_CORRELATOR_H +#define INCLUDED_GR_SIMPLE_CORRELATOR_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief inverse of simple_framer (more or less) + * \ingroup packet_operators_blk + * \ingroup deprecated_blk + */ + class DIGITAL_API simple_correlator : virtual public gr_block + { + public: + // gr::digital::simple_correlator::sptr + typedef boost::shared_ptr<simple_correlator> sptr; + + static sptr make(int payload_bytesize); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_SIMPLE_CORRELATOR_H */ diff --git a/gr-digital/include/digital/simple_framer.h b/gr-digital/include/digital/simple_framer.h new file mode 100644 index 000000000..951e13d8f --- /dev/null +++ b/gr-digital/include/digital/simple_framer.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,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_GR_SIMPLE_FRAMER_H +#define INCLUDED_GR_SIMPLE_FRAMER_H + +#include <digital/api.h> +#include <gr_block.h> + +namespace gr { + namespace digital { + + /*! + * \brief add sync field, seq number and command field to payload + * \ingroup packet_operators_blk + * \ingroup deprecated_blk + * + * \details + * Takes in enough samples to create a full output frame. The + * frame is prepended with the GRSF_SYNC (defind in + * simple_framer_sync.h) and an 8-bit sequence number. + */ + class DIGITAL_API simple_framer : virtual public gr_block + { + public: + // gr::digital::simple_framer::sptr + typedef boost::shared_ptr<simple_framer> sptr; + + /*! + * Make a simple_framer block. + * + * \param payload_bytesize The size of the payload in bytes. + */ + static sptr make(int payload_bytesize); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_SIMPLE_FRAMER_H */ diff --git a/gr-digital/include/digital/simple_framer_sync.h b/gr-digital/include/digital/simple_framer_sync.h new file mode 100644 index 000000000..f6c8f148e --- /dev/null +++ b/gr-digital/include/digital/simple_framer_sync.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2005,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_GR_SIMPLE_FRAMER_SYNC_H +#define INCLUDED_GR_SIMPLE_FRAMER_SYNC_H + +namespace gr { + namespace digital { + + /*! + * Here are a couple of maximum length sequences (m-sequences) + * that were generated by the the "mseq" matlab/octave code + * downloaded from: <a + * href="http://www.mathworks.com/matlabcentral/fileexchange/990">http://www.mathworks.com/matlabcentral/fileexchange/990</a> + * + * <pre> + * 31-bit m-sequence: + * 0110100100001010111011000111110 + * 0x690AEC76 (padded on right with a zero) + * + * 63-bit m-sequence: + * 101011001101110110100100111000101111001010001100001000001111110 + * 0xACDDA4E2F28C20FC (padded on right with a zero) + * </pre> + */ + static const unsigned long long GRSF_SYNC = 0xacdda4e2f28c20fcULL; + + static const int GRSF_BITS_PER_BYTE = 8; + static const int GRSF_SYNC_OVERHEAD = sizeof(GRSF_SYNC); + static const int GRSF_PAYLOAD_OVERHEAD = 1; // 1 byte seqno + static const int GRSF_TAIL_PAD = 1; // one byte trailing padding + static const int GRSF_OVERHEAD = GRSF_SYNC_OVERHEAD + GRSF_PAYLOAD_OVERHEAD + GRSF_TAIL_PAD; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_GR_SIMPLE_FRAMER_SYNC_H */ |