diff options
Diffstat (limited to 'gr-digital/lib/timing_error_detector.h')
-rw-r--r-- | gr-digital/lib/timing_error_detector.h | 513 |
1 files changed, 513 insertions, 0 deletions
diff --git a/gr-digital/lib/timing_error_detector.h b/gr-digital/lib/timing_error_detector.h new file mode 100644 index 0000000000..fd569ba360 --- /dev/null +++ b/gr-digital/lib/timing_error_detector.h @@ -0,0 +1,513 @@ +/* -*- c++ -*- */ +/* + * Copyright (C) 2017 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 file; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_DIGITAL_TIMING_ERROR_DETECTOR_H +#define INCLUDED_DIGITAL_TIMING_ERROR_DETECTOR_H + +#include <gnuradio/gr_complex.h> +#include <gnuradio/digital/timing_error_detector_type.h> +#include <gnuradio/digital/constellation.h> +#include <deque> + +namespace gr { + namespace digital { + + /*! + * \brief Base class for the composite symbol clock timing error + * detector object used by the symbol_synchronizer_xx blocks. + * \ingroup internal + * + * \details + * This is the base class for the symbol clock timing error detector + * object used by the symbol_synchronizer_xx blocks to provide a + * user selectable timing error detector type. + * + * This base class provides the enumeration type for the available + * types of timing error detectors. + * + * This base class also provides most of the methods update, manage, and + * store the data points required to compute the symbol clock timing error, + * and the timing error result itself. + * + * The derived classes only have to provide the simple functions + * to actually compute the timing error. + */ + class timing_error_detector + { + public: + + /*! + * \brief Create a timing error detector object of the specified + * type + * \param type The type/algorithm to use for the timing error detector + * \param constellation A constellation to be used as a decision slicer + * for decision directed timing error detector + * algorithms + */ + static timing_error_detector *make(enum ted_type type, + constellation_sptr constellation = + constellation_sptr()); + + virtual ~timing_error_detector() {}; + + /*! + * \brief Return the number of input samples per symbol this timing + * error detector algorithm requires. + */ + virtual int inputs_per_symbol() { return d_inputs_per_symbol; } + + /*! + * \brief Provide a complex input sample to the TED algorithm + * \param x the input sample + * \param dx the derivative at the input sample, if required by the + * timinig error detector algorithm + */ + virtual void input(const gr_complex &x, + const gr_complex &dx = gr_complex(0.0f, 0.0f)); + + /*! + * \brief Provide a float input sample to the TED algorithm + * \param x the input sample + * \param dx the derivative at the input sample, if required by the + * timinig error detector algorithm + */ + virtual void input(float x, + float dx = 0.0f); + + /*! + * \brief Return if this timing error detector algorithm requires a + * look-ahead input sample to be input to produce a new error estimate + * for the symbol sampling instant. + */ + virtual bool needs_lookahead() { return d_needs_lookahead; } + + /*! + * \brief Provide a complex input lookahead sample to the TED algorithm + * \param x the input lookahead sample + * \param dx the derivative at the input lookahead sample, if required + * by the timinig error detector algorithm + */ + virtual void input_lookahead(const gr_complex &x, + const gr_complex &dx = + gr_complex(0.0f, 0.0f)); + + /*! + * \brief Provide a float input lookahead sample to the TED algorithm + * \param x the input lookahead sample + * \param dx the derivative at the input lookahead sample, if required + * by the timinig error detector algorithm + */ + virtual void input_lookahead(float x, + float dx = 0.0f); + + /*! + * \brief Return if this timing error detector algorithm requires + * derivative input samples in addition to normal input samples. + */ + virtual bool needs_derivative() { return d_needs_derivative; } + + /*! + * \brief Return the current symbol timing error estimate + */ + virtual float error() { return d_error; } + + /*! + * \brief Revert the timing error detector processing state back one + * step. + * \param preserve_error If true, don't revert the error estimate. + */ + virtual void revert(bool preserve_error = false); + + /*! + * \brief Reset the timing error detector + */ + virtual void sync_reset(); + + private: + enum ted_type d_type; + + protected: + /*! + * \brief Create a timing error detector abstract base class object + * object + * \param type The type/algorithm to use for the timing error detector + * \param inputs_per_symbol The input samples per symbol this TED + * algorithm requires + * \param error_computation_depth The number of input samples this TED + * algorithm needs to compute the error + * \param needs_lookahead True if this TED algorithm needs a lookahead + * input sample to compute the error for the + * symbol sampling instant + * \param needs_derivative True if this TED algorithm needs a derivative + * input sample in addition to the normal input + * sample + * \param constellation A constellation to be used as a decision slicer + * for decision directed timing error detector + * algorithms + */ + timing_error_detector(enum ted_type type, + int inputs_per_symbol, + int error_computation_depth, + bool needs_lookahead = false, + bool needs_derivative = false, + constellation_sptr constellation = + constellation_sptr()); + + /*! + * \brief Advance the TED input clock, so the input() methods will + * compute the TED error term at the proper symbol sampling instant. + */ + void advance_input_clock() { + d_input_clock = (d_input_clock + 1) % d_inputs_per_symbol; + } + + /*! + * \brief Revert the TED input clock one step + */ + void revert_input_clock() + { + if (d_input_clock == 0) + d_input_clock = d_inputs_per_symbol - 1; + else + d_input_clock--; + } + + /*! + * \brief Reset the TED input clock, so the next input clock advance + * corresponds to a symbol sampling instant. + */ + void sync_reset_input_clock() { + d_input_clock = d_inputs_per_symbol - 1; + } + + /*! + * \brief Convert the soft symbol sample into a hard symbol decision. + * \param x the soft input symbol sample + */ + gr_complex slice(const gr_complex &x); + + /*! + * \brief Compute the TED error term for complex input samples + */ + virtual float compute_error_cf() = 0; + + /*! + * \brief Compute the TED error term for float input samples + */ + virtual float compute_error_ff() = 0; + + constellation_sptr d_constellation; + float d_error; + float d_prev_error; + int d_inputs_per_symbol; + int d_input_clock; + int d_error_depth; + std::deque<gr_complex> d_input; + std::deque<gr_complex> d_decision; + std::deque<gr_complex> d_input_derivative; + bool d_needs_lookahead; + bool d_needs_derivative; + }; + + /*! + * \brief Mueller and Müller (M&M) timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Mueller and Müller (M&M) timing error detector algorithm + * class. It is a decision directed timing error detector, and requires + * an input slicer constellation to make decisions. + * + * See equation (49) of: + * Mueller, Kurt H., Müller, Markus, "Timing Recovery in Digital + * Synchronous Data Receivers", _IEEE_Transactions_on_Communications_, + * Vol. COM-24, No. 5, May 1976, pp. 516-531 + */ + class ted_mueller_and_muller : public timing_error_detector + { + public: + /*! + * \brief Create a Mueller and Müller (M&M) timing error detector + * \param constellation A constellation to be used as a decision slicer + */ + ted_mueller_and_muller(constellation_sptr constellation) + : timing_error_detector(TED_MUELLER_AND_MULLER, + 1, 2, false, false, constellation) + {} + ~ted_mueller_and_muller() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Modified Mueller and Müller (M&M) timing error detector algorithm + * class + * \ingroup internal + * + * \details + * This is the modified Mueller and Müller (M&M) timing error detector + * algorithm class. It is a decision directed timing error detector, and + * requires an input slicer constellation to make decisions. + * + * The modification of the standard M&M TED is done to remove + * self-noise that is present in the standard M&M TED. + * + * See: + * 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 ted_mod_mueller_and_muller : public timing_error_detector + { + public: + /*! + * \brief Create a modified Mueller and Müller (M&M) timing error + * detector + * \param constellation A constellation to be used as a decision slicer + */ + ted_mod_mueller_and_muller(constellation_sptr constellation) + : timing_error_detector(TED_MOD_MUELLER_AND_MULLER, + 1, 3, false, false, constellation) + {} + ~ted_mod_mueller_and_muller() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Zero Crossing timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Zero Crossing timing error detector algorithm class. + * It is a decision directed timing error detector, and + * requires an input slicer constellation to make decisions. + */ + class ted_zero_crossing : public timing_error_detector + { + public: + /*! + * \brief Create a Zero Crossing timing error detector + * \param constellation A constellation to be used as a decision slicer + */ + ted_zero_crossing(constellation_sptr constellation) + : timing_error_detector(TED_ZERO_CROSSING, + 2, 3, false, false, constellation) + {} + ~ted_zero_crossing() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Gardner timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Gardner timing error detector algorithm class. + * + * See: + * F.M. Gardner, “A BPSK/QPSK Timing Error Detector for Sampled Receivers”, + * IEEE Trans., COM-34, (5), 1988, pp. 423 – 429. + */ + class ted_gardner : public timing_error_detector + { + public: + /*! + * \brief Create a Gardner timing error detector + */ + ted_gardner() + : timing_error_detector(TED_GARDNER, + 2, 3, false, false, + constellation_sptr()) + {} + ~ted_gardner() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Early-Late timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Early-Late timing error detector algorithm class. + * It requires a lookahead sample to compute the symbol timing error + * at the symbol sampling instant. + */ + class ted_early_late : public timing_error_detector + { + public: + /*! + * \brief Create a Early-Late timing error detector + */ + ted_early_late() + : timing_error_detector(TED_EARLY_LATE, + 2, 2, true, false, + constellation_sptr()) + {} + ~ted_early_late() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Generalized MSK timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Generalized MSK timing error detector algorithm class. + * It operates on the CPM MSK signal directly and not the FM pulses. + * + * See: + * A.N. D'Andrea, U. Mengali, R. Reggiannini, "A digital approach to clock + * recovery in generalized minimum shift keying", IEEE Transactions on + * Vehicular Technology, Vol. 39, Issue 3, August 1990, pp. 227-234 + */ + class ted_generalized_msk : public timing_error_detector + { + public: + /*! + * \brief Create a Generalized MSK timing error detector + */ + ted_generalized_msk() + : timing_error_detector(TED_DANDREA_AND_MENGALI_GEN_MSK, + 2, 4, false, false, constellation_sptr()) + {} + ~ted_generalized_msk() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Gaussian MSK timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Gaussian MSK timing error detector algorithm class. + * It operates on the CPM MSK signal directly and not the FM pulses. + * + * See: + * U. Mengali, A.N. D'Andrea, _Synchronization_Techniques_for_Digital_ + * Receviers_, New York, Plenum Press 1997 + */ + class ted_gaussian_msk : public timing_error_detector + { + public: + /*! + * \brief Create a Generalized MSK timing error detector + */ + ted_gaussian_msk() + : timing_error_detector(TED_MENGALI_AND_DANDREA_GMSK, + 2, 4, false, false, constellation_sptr()) + {} + ~ted_gaussian_msk() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Signal times Slope Maximum Likelyhood solution approximation + * timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Signal times Slope Maximum Likelyhood solution approximation + * timing error detector algorithm class. This approximation is good for + * small signals (< 1.0) and/or situations with low SNR. + * + * See equation (5) and the 2 following paragraphs of: + * Fredric J. Harris, Michael Rice, "Multirate Digital Filters for + * Symbol Timing Synchronization in Software Defined Radios", + * _IEEE_Journal_on_Selected_Areas_in_Communications_, Vol. 19, No. 12, + * December 2001, pp. 2346 - 2357 + */ + class ted_signal_times_slope_ml : public timing_error_detector + { + public: + /*! + * \brief Create a Signal times Slope Maximum Likelyhood solution + * approximation timing error detector + */ + ted_signal_times_slope_ml() + : timing_error_detector(TED_SIGNAL_TIMES_SLOPE_ML, + 1, 1, false, true, constellation_sptr()) + {} + ~ted_signal_times_slope_ml() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + /*! + * \brief Signum times Slope Maximum Likelyhood solution approximation + * timing error detector algorithm class + * \ingroup internal + * + * \details + * This is the Signum times Slope Maximum Likelyhood solution approximation + * timing error detector algorithm class. This approximation is good for + * large signals (> 1.0) and/or situations with high SNR. + * + * See equation (5) and the 2 following paragraphs of: + * Fredric J. Harris, Michael Rice, "Multirate Digital Filters for + * Symbol Timing Synchronization in Software Defined Radios", + * _IEEE_Journal_on_Selected_Areas_in_Communications_, Vol. 19, No. 12, + * December 2001, pp. 2346 - 2357 + */ + class ted_signum_times_slope_ml : public timing_error_detector + { + public: + /*! + * \brief Create a Signum times Slope Maximum Likelyhood solution + * approximation timing error detector + */ + ted_signum_times_slope_ml() + : timing_error_detector(TED_SIGNUM_TIMES_SLOPE_ML, + 1, 1, false, true, constellation_sptr()) + {} + ~ted_signum_times_slope_ml() {}; + + private: + float compute_error_cf(); + float compute_error_ff(); + }; + + } /* namespace digital */ +} /* namespace gr */ + +#endif /* INCLUDED_DIGITAL_TIMING_ERROR_DETECTOR_H */ |