diff options
Diffstat (limited to 'gnuradio-core/src')
26 files changed, 964 insertions, 426 deletions
diff --git a/gnuradio-core/src/guile/tests/general_ctors.test b/gnuradio-core/src/guile/tests/general_ctors.test index 813574bca..a0e39855c 100644 --- a/gnuradio-core/src/guile/tests/general_ctors.test +++ b/gnuradio-core/src/guile/tests/general_ctors.test @@ -244,13 +244,13 @@ (pass-if (true? (gr:phase-modulator-fc 0))) ;;; ./general/gr_pll_carriertracking_cc.h -(pass-if (true? (gr:pll-carriertracking-cc 0 0 0 0))) +(pass-if (true? (gr:pll-carriertracking-cc 0 0 0))) ;;; ./general/gr_pll_freqdet_cf.h -(pass-if (true? (gr:pll-freqdet-cf 0 0 0 0))) +(pass-if (true? (gr:pll-freqdet-cf 0 0 0))) ;;; ./general/gr_pll_refout_cc.h -(pass-if (true? (gr:pll-refout-cc 0 0 0 0))) +(pass-if (true? (gr:pll-refout-cc 0 0 0))) ;;; ./general/gr_pn_correlator_cc.h (pass-if (true? (gr:pn-correlator-cc 1 1 1))) diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc index b5a5aed7d..a939609f3 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc @@ -60,7 +60,7 @@ gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float loop_bw, gr_make_io_signaturev (1, 4, iosig)), d_updated (false), d_nfilters(filter_size), d_max_dev(max_rate_deviation), - d_osps(osps) + d_osps(osps), d_error(0) { d_nfilters = filter_size; d_sps = floor(sps); @@ -367,51 +367,51 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, int nrequired = ninput_items[0] - d_taps_per_filter - d_osps; int i = 0, count = 0; - float error, error_r, error_i; + float error_r, error_i; // produce output as long as we can and there are enough input samples while((i < noutput_items-d_osps) && (count < nrequired)) { - d_filtnum = (int)floor(d_k); - - // Keep the current filter number in [0, d_nfilters] - // If we've run beyond the last filter, wrap around and go to next sample - // If we've go below 0, wrap around and go to previous sample - while(d_filtnum >= d_nfilters) { - d_k -= d_nfilters; - d_filtnum -= d_nfilters; - count += 1; - } - while(d_filtnum < 0) { - d_k += d_nfilters; - d_filtnum += d_nfilters; - count -= 1; - } - for(int k = 0; k < d_osps; k++) { + d_filtnum = (int)floor(d_k); + + // Keep the current filter number in [0, d_nfilters] + // If we've run beyond the last filter, wrap around and go to next sample + // If we've go below 0, wrap around and go to previous sample + while(d_filtnum >= d_nfilters) { + d_k -= d_nfilters; + d_filtnum -= d_nfilters; + count += 1; + } + while(d_filtnum < 0) { + d_k += d_nfilters; + d_filtnum += d_nfilters; + count -= 1; + } + out[i+k] = d_filters[d_filtnum]->filter(&in[count+k]); + d_k = d_k + d_rate_i + d_rate_f; // update phase + + if(output_items.size() == 4) { + err[i] = d_error; + outrate[i] = d_rate_f; + outk[i] = d_k; + } } + // Update the phase and rate estimates for this symbol gr_complex diff = d_diff_filters[d_filtnum]->filter(&in[count]); error_r = out[i].real() * diff.real(); error_i = out[i].imag() * diff.imag(); - error = (error_i + error_r) / 2.0; // average error from I&Q channel - - // Run the control loop to update the current phase (k) and tracking rate - d_rate_f = d_rate_f + d_beta*error; - d_k = d_k + d_alpha*error + d_rate_i + d_rate_f; + d_error = (error_i + error_r) / 2.0; // average error from I&Q channel + + // Run the control loop to update the current phase (k) and + // tracking rate estimates based on the error value + d_rate_f = d_rate_f + d_beta*d_error; + d_k = d_k + d_alpha*d_error; // Keep our rate within a good range d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev); - if(output_items.size() == 4) { - // FIXME: don't really know what to do about d_osps>1 - for(int k = 0; k < d_osps; k++) { - err[i] = diff.real(); - outrate[i] = d_rate_f; - outk[i] = d_k; - } - } - i+=d_osps; count += (int)floor(d_sps); } diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h index 1f96b9000..2eae11807 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h @@ -155,6 +155,7 @@ class GR_CORE_API gr_pfb_clock_sync_ccf : public gr_block float d_max_dev; int d_filtnum; int d_osps; + float d_error; /*! * Build the polyphase filterbank timing synchronizer. diff --git a/gnuradio-core/src/lib/general/CMakeLists.txt b/gnuradio-core/src/lib/general/CMakeLists.txt index 1cd9c6bd1..cb3f0da4b 100644 --- a/gnuradio-core/src/lib/general/CMakeLists.txt +++ b/gnuradio-core/src/lib/general/CMakeLists.txt @@ -96,6 +96,7 @@ LIST(APPEND gnuradio_core_sources LIST(APPEND test_gnuradio_core_sources ${CMAKE_CURRENT_SOURCE_DIR}/qa_general.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_circular_file.cc + ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_cpm.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_firdes.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_gr_fxpt_nco.cc @@ -189,6 +190,7 @@ SET(gr_core_general_triple_threats gr_conjugate_cc gr_copy gr_cpfsk_bc + gr_cpm gr_ctcss_squelch_ff gr_decode_ccsds_27_fb gr_diff_decoder_bb diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index f210cee39..fe545f98c 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -55,6 +55,7 @@ libgeneral_la_SOURCES = \ gr_copy.cc \ gr_count_bits.cc \ gr_cpfsk_bc.cc \ + gr_cpm.cc \ gr_ctcss_squelch_ff.cc \ gr_decode_ccsds_27_fb.cc \ gr_deinterleave.cc \ @@ -176,6 +177,7 @@ libgeneral_la_SOURCES = \ libgeneral_qa_la_SOURCES = \ qa_general.cc \ qa_gr_circular_file.cc \ + qa_gr_cpm.cc \ qa_gr_firdes.cc \ qa_gr_fxpt.cc \ qa_gr_fxpt_nco.cc \ @@ -203,6 +205,7 @@ grinclude_HEADERS = \ gr_copy.h \ gr_count_bits.h \ gr_cpfsk_bc.h \ + gr_cpm.h \ gr_ctcss_squelch_ff.h \ gr_decode_ccsds_27_fb.h \ gr_diff_decoder_bb.h \ @@ -340,6 +343,7 @@ grinclude_HEADERS = \ noinst_HEADERS = \ qa_general.h \ qa_gr_circular_file.h \ + qa_gr_cpm.h \ qa_gr_firdes.h \ qa_gr_fxpt.h \ qa_gr_fxpt_nco.h \ @@ -367,6 +371,7 @@ swiginclude_HEADERS = \ gr_conjugate_cc.i \ gr_copy.i \ gr_cpfsk_bc.i \ + gr_cpm.i \ gr_ctcss_squelch_ff.i \ gr_decode_ccsds_27_fb.i \ gr_diff_decoder_bb.i \ diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index f9adff3fa..e965eea64 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * Copyright 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -137,6 +137,7 @@ #include <gr_annotator_alltoall.h> #include <gr_annotator_1to1.h> #include <gr_burst_tagger.h> +#include <gr_cpm.h> %} %include "gri_control_loop.i" @@ -254,3 +255,4 @@ %include "gr_annotator_alltoall.i" %include "gr_annotator_1to1.i" %include "gr_burst_tagger.i" +%include "gr_cpm.i" diff --git a/gnuradio-core/src/lib/general/gr_cpm.cc b/gnuradio-core/src/lib/general/gr_cpm.cc new file mode 100644 index 000000000..a00526b52 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_cpm.cc @@ -0,0 +1,214 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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. + */ + +// Calculate the taps for the CPM phase responses + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cmath> +#include <cfloat> +#include <gr_cpm.h> + +#ifndef M_TWOPI +# define M_TWOPI (2*M_PI) +#endif + +//! Normalised sinc function, sinc(x)=sin(pi*x)/pi*x +inline double +sinc(double x) +{ + if (x == 0) { + return 1.0; + } + + return sin(M_PI * x) / (M_PI * x); +} + + +//! Taps for L-RC CPM (Raised cosine of length L symbols) +std::vector<float> +generate_cpm_lrc_taps(unsigned samples_per_sym, unsigned L) +{ + std::vector<float> taps(samples_per_sym * L, 1.0/L/samples_per_sym); + for (unsigned i = 0; i < samples_per_sym * L; i++) { + taps[i] *= 1 - cos(M_TWOPI * i / L / samples_per_sym); + } + + return taps; +} + + +/*! Taps for L-SRC CPM (Spectral raised cosine of length L symbols). + * + * L-SRC has a time-continuous phase response function of + * + * g(t) = 1/LT * sinc(2t/LT) * cos(beta * 2pi t / LT) / (1 - (4beta / LT * t)^2) + * + * which is the Fourier transform of a cos-rolloff function with rolloff + * beta, and looks like a sinc-function, multiplied with a rolloff term. + * We return the main lobe of the sinc, i.e., everything between the + * zero crossings. + * The time-discrete IR is thus + * + * g(k) = 1/Ls * sinc(2k/Ls) * cos(beta * pi k / Ls) / (1 - (4beta / Ls * k)^2) + * where k = 0...Ls-1 + * and s = samples per symbol. + */ +std::vector<float> +generate_cpm_lsrc_taps(unsigned samples_per_sym, unsigned L, double beta) +{ + double Ls = (double) L * samples_per_sym; + std::vector<double> taps_d(L * samples_per_sym, 0.0); + std::vector<float> taps(L * samples_per_sym, 0.0); + + double sum = 0; + for (unsigned i = 0; i < samples_per_sym * L; i++) { + double k = i - Ls/2; // Causal to acausal + + taps_d[i] = 1.0 / Ls * sinc(2.0 * k / Ls); + + // For k = +/-Ls/4*beta, the rolloff term's cos-function becomes zero + // and the whole thing converges to PI/4 (to prove this, use de + // l'hopital's rule). + if (fabs(fabs(k) - Ls/4/beta) < 2*DBL_EPSILON) { + taps_d[i] *= M_PI_4; + } else { + double tmp = 4.0 * beta * k / Ls; + taps_d[i] *= cos(beta * M_TWOPI * k / Ls) / (1 - tmp * tmp); + } + sum += taps_d[i]; + } + for (unsigned i = 0; i < samples_per_sym * L; i++) { + taps[i] = (float) taps_d[i] / sum; + } + + return taps; +} + + +//! Taps for L-REC CPM (Rectangular pulse shape of length L symbols) +std::vector<float> +generate_cpm_lrec_taps(unsigned samples_per_sym, unsigned L) +{ + return std::vector<float>(samples_per_sym * L, 1.0/L/samples_per_sym); +} + + +//! Helper function for TFM +double tfm_g0(double k, double sps) +{ + if (fabs(k) < 2 * DBL_EPSILON) { + return 1.145393004159143; // 1 + pi^2/48 / sqrt(2) + } + + const double pi2_24 = 0.411233516712057; // pi^2/24 + double f = M_PI * k / sps; + return sinc(k/sps) - pi2_24 * (2 * sin(f) - 2*f*cos(f) - f*f*sin(f)) / (f*f*f); +} + + +//! Taps for TFM CPM (Tamed frequency modulation) +// +// See [2, Chapter 2.7.2]. +// +// [2]: Anderson, Aulin and Sundberg; Digital Phase Modulation +std::vector<float> +generate_cpm_tfm_taps(unsigned sps, unsigned L) +{ + unsigned causal_shift = sps * L / 2; + std::vector<double> taps_d(sps * L, 0.0); + std::vector<float> taps(sps * L, 0.0); + + double sum = 0; + for (unsigned i = 0; i < sps * L; i++) { + double k = (double)(((int)i) - ((int)causal_shift)); // Causal to acausal + + taps_d[i] = tfm_g0(k - sps, sps) + + 2 * tfm_g0(k, sps) + + tfm_g0(k + sps, sps); + sum += taps_d[i]; + } + for (unsigned i = 0; i < sps * L; i++) { + taps[i] = (float) taps_d[i] / sum; + } + + return taps; +} + + +//! Taps for Gaussian CPM. Phase response is truncated after \p L symbols. +// \p bt sets the 3dB-time-bandwidth product. +// +// Note: for h = 0.5, this is the phase response for GMSK. +// +// This C99-compatible formula for the taps is taken straight +// from [1, Chapter 9.2.3]. +// A version in Q-notation can be found in [2, Chapter 2.7.2]. +// +// [1]: Karl-Dirk Kammeyer; Nachrichtenübertragung, 4th Edition. +// [2]: Anderson, Aulin and Sundberg; Digital Phase Modulation +// +std::vector<float> +generate_cpm_gaussian_taps(unsigned samples_per_sym, unsigned L, double bt) +{ + double Ls = (double) L * samples_per_sym; + std::vector<double> taps_d(L * samples_per_sym, 0.0); + std::vector<float> taps(L * samples_per_sym, 0.0); + + // alpha = sqrt(2/ln(2)) * pi * BT + double alpha = 5.336446256636997 * bt; + for (unsigned i = 0; i < samples_per_sym * L; i++) { + double k = i - Ls/2; // Causal to acausal + taps_d[i] = (erf(alpha * (k / samples_per_sym + 0.5)) - + erf(alpha * (k / samples_per_sym - 0.5))) + * 0.5 / samples_per_sym; + taps[i] = (float) taps_d[i]; + } + + return taps; +} + + +std::vector<float> +gr_cpm::phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta) +{ + switch (type) { + case LRC: + return generate_cpm_lrc_taps(samples_per_sym, L); + + case LSRC: + return generate_cpm_lsrc_taps(samples_per_sym, L, beta); + + case LREC: + return generate_cpm_lrec_taps(samples_per_sym, L); + + case TFM: + return generate_cpm_tfm_taps(samples_per_sym, L); + + case GAUSSIAN: + return generate_cpm_gaussian_taps(samples_per_sym, L, beta); + + default: + return generate_cpm_lrec_taps(samples_per_sym, 1); + } +} + diff --git a/gnuradio-core/src/lib/general/gr_cpm.h b/gnuradio-core/src/lib/general/gr_cpm.h new file mode 100644 index 000000000..ef2ff8414 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_cpm.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_CPM_H +#define INCLUDED_GR_CPM_H + +#include <gr_core_api.h> +#include <vector> + +class GR_CORE_API gr_cpm +{ + public: + enum cpm_type { + LRC, + LSRC, + LREC, + TFM, + GAUSSIAN, + GENERIC = 999 + }; + + /*! \brief Return the taps for an interpolating FIR filter (gr_interp_fir_filter_fff). + * + * These taps represent the phase response \f$g(k)\f$ for use in a CPM modulator, + * see also gr_cpmmod_bc. + * + * \param type The CPM type (Rectangular, Raised Cosine, Spectral Raised Cosine, + * Tamed FM or Gaussian). + * \param samples_per_sym Samples per symbol. + * \param L The length of the phase response in symbols. + * \param beta For Spectral Raised Cosine, this is the rolloff factor. For Gaussian + * phase responses, this the 3dB-time-bandwidth product. For all other + * cases, it is ignored. + * + * Output: returns a vector of length \a K = \p samples_per_sym x \p L. + * This can be used directly in an interpolating FIR filter such as + * gr_interp_fir_filter_fff with interpolation factor \p samples_per_sym. + * + * All phase responses are normalised s.t. \f$ \sum_{k=0}^{K-1} g(k) = 1\f$; this will cause + * a maximum phase change of \f$ h \cdot \pi\f$ between two symbols, where \a h is the + * modulation index. + * + * The following phase responses can be generated: + * - LREC: Rectangular phase response. + * - LRC: Raised cosine phase response, looks like 1 - cos(x). + * - LSRC: Spectral raised cosine. This requires a rolloff factor beta. + * The phase response is the Fourier transform of raised cosine + * function. + * - TFM: Tamed frequency modulation. This scheme minimizes phase change for + * rapidly varying input symbols. + * - GAUSSIAN: A Gaussian phase response. For a modulation index h = 1/2, this + * results in GMSK. + * + * A short description of all these phase responses can be found in [1]. + * + * [1]: Anderson, Aulin and Sundberg; Digital Phase Modulation + */ + static std::vector<float> + phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta=0.3); +}; + +#endif /* INCLUDED_GR_CPM_H */ + diff --git a/gnuradio-core/src/lib/general/gr_cpm.i b/gnuradio-core/src/lib/general/gr_cpm.i new file mode 100644 index 000000000..f01aba34e --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_cpm.i @@ -0,0 +1,40 @@ +/* -*- C++ -*- */ +/* + * Copyright 2010 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. + */ + +%rename(cpm) gr_cpm; + +class gr_cpm +{ + public: + enum cpm_type { + LRC, + LSRC, + LREC, + TFM, + GAUSSIAN, + GENERIC = 999 + }; + + static std::vector<float> + phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta=0.3); +}; + diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc index 19ab316a1..583e0eb70 100644 --- a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc +++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2010 Free Software Foundation, Inc. + * Copyright 2006,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,22 +30,24 @@ #include <math.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif gr_pll_carriertracking_cc_sptr -gr_make_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq) +gr_make_pll_carriertracking_cc (float loop_bw, float max_freq, float min_freq) { - return gnuradio::get_initial_sptr(new gr_pll_carriertracking_cc (alpha, beta, max_freq, min_freq)); + return gnuradio::get_initial_sptr(new gr_pll_carriertracking_cc (loop_bw, max_freq, min_freq)); } -gr_pll_carriertracking_cc::gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq) +gr_pll_carriertracking_cc::gr_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq) : gr_sync_block ("pll_carriertracking_cc", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature (1, 1, sizeof (gr_complex))), - d_alpha(alpha), d_beta(beta), - d_max_freq(max_freq), d_min_freq(min_freq), - d_phase(0), d_freq((max_freq+min_freq)/2), - d_locksig(0),d_lock_threshold(0),d_squelch_enable(false) + gri_control_loop(loop_bw, max_freq, min_freq), + d_locksig(0), d_lock_threshold(0), d_squelch_enable(false) { } @@ -72,7 +74,7 @@ gr_pll_carriertracking_cc::phase_detector(gr_complex sample,float ref_phase) bool gr_pll_carriertracking_cc::lock_detector(void) { - return (fabs(d_locksig) > d_lock_threshold); + return (fabsf(d_locksig) > d_lock_threshold); } bool @@ -100,17 +102,16 @@ gr_pll_carriertracking_cc::work (int noutput_items, for (int i = 0; i < noutput_items; i++){ error = phase_detector(iptr[i],d_phase); - - d_freq = d_freq + d_beta * error; - d_phase = mod_2pi(d_phase + d_freq + d_alpha * error); - - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; - gr_sincosf(d_phase,&t_imag,&t_real); - optr[i] = iptr[i] * gr_complex(t_real,-t_imag); - d_locksig = d_locksig * (1.0 - d_alpha) + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + + gr_sincosf(d_phase, &t_imag, &t_real); + optr[i] = iptr[i] * gr_complex(t_real, -t_imag); + + d_locksig = d_locksig * (1.0 - d_alpha) + \ + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag); if ((d_squelch_enable) && !lock_detector()) optr[i] = 0; diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h index 27e74f111..db74bb101 100644 --- a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h +++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,206 Free Software Foundation, Inc. + * Copyright 2004,2006,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -25,12 +25,14 @@ #include <gr_core_api.h> #include <gr_sync_block.h> +#include <gri_control_loop.h> class gr_pll_carriertracking_cc; typedef boost::shared_ptr<gr_pll_carriertracking_cc> gr_pll_carriertracking_cc_sptr; -GR_CORE_API gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta, - float max_freq, float min_freq); +GR_CORE_API gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq); /*! * \brief Implements a PLL which locks to the input frequency and outputs the * input signal mixed with that carrier. @@ -42,19 +44,20 @@ GR_CORE_API gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float * the input and outputs that signal, downconverted to DC * * All settings max_freq and min_freq are in terms of radians per sample, - * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian) - * and beta is the frequency gain (second order, units of radians per sample per radian) + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc */ -class GR_CORE_API gr_pll_carriertracking_cc : public gr_sync_block +class GR_CORE_API gr_pll_carriertracking_cc : public gr_sync_block, public gri_control_loop { - friend GR_CORE_API gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta, - float max_freq, float min_freq); + friend GR_CORE_API gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq); - float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq,d_locksig,d_lock_threshold; + float d_locksig,d_lock_threshold; bool d_squelch_enable; - gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq); + gr_pll_carriertracking_cc (float loop_bw, float max_freq, float min_freq); int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i index 3e84fccbe..d309111b2 100644 --- a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i +++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,13 +23,14 @@ GR_SWIG_BLOCK_MAGIC(gr,pll_carriertracking_cc); gr_pll_carriertracking_cc_sptr -gr_make_pll_carriertracking_cc (float alpha, float beta, - float max_freq, float min_freq); +gr_make_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq); -class gr_pll_carriertracking_cc : public gr_sync_block +class gr_pll_carriertracking_cc : public gr_sync_block, public gri_control_loop { private: - gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq); + gr_pll_carriertracking_cc (float loop_bw, float max_freq, float min_freq); public: bool lock_detector(void); bool squelch_enable(bool); diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc index 1f17f2afc..0ae773e6e 100644 --- a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc +++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,8 +20,6 @@ * Boston, MA 02110-1301, USA. */ -// WARNING: this file is machine generated. Edits will be over written - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -31,21 +29,21 @@ #include <math.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif gr_pll_freqdet_cf_sptr -gr_make_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq) +gr_make_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq) { - return gnuradio::get_initial_sptr(new gr_pll_freqdet_cf (alpha, beta, max_freq, min_freq)); + return gnuradio::get_initial_sptr(new gr_pll_freqdet_cf (loop_bw, max_freq, min_freq)); } -gr_pll_freqdet_cf::gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq) +gr_pll_freqdet_cf::gr_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq) : gr_sync_block ("pll_freqdet_cf", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature (1, 1, sizeof (float))), - d_alpha(alpha), d_beta(beta), - d_max_freq(max_freq), d_min_freq(min_freq), - d_phase(0), d_freq((max_freq+min_freq)/2) + gri_control_loop(loop_bw, max_freq, min_freq) { } @@ -70,8 +68,8 @@ gr_pll_freqdet_cf::phase_detector(gr_complex sample,float ref_phase) int gr_pll_freqdet_cf::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { const gr_complex *iptr = (gr_complex *) input_items[0]; float *optr = (float *) output_items[0]; @@ -82,13 +80,10 @@ gr_pll_freqdet_cf::work (int noutput_items, while (size-- > 0) { error = phase_detector(*iptr++,d_phase); - d_freq = d_freq + d_beta * error; - d_phase = mod_2pi(d_phase + d_freq + d_alpha * error); - - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; + advance_loop(error); + phase_wrap(); + frequency_limit(); + *optr++ = d_freq; } return noutput_items; diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h index 6ed1f99c2..336f3fd31 100644 --- a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h +++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -25,12 +25,14 @@ #include <gr_core_api.h> #include <gr_sync_block.h> +#include <gri_control_loop.h> class gr_pll_freqdet_cf; typedef boost::shared_ptr<gr_pll_freqdet_cf> gr_pll_freqdet_cf_sptr; -GR_CORE_API gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, - float max_freq, float min_freq); +GR_CORE_API gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw, + float max_freq, + float min_freq); /*! * \brief Implements a PLL which locks to the input frequency and outputs * an estimate of that frequency. Useful for FM Demod. @@ -41,24 +43,24 @@ GR_CORE_API gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float be * This PLL locks onto a [possibly noisy] reference carrier on * the input and outputs an estimate of that frequency in radians per sample. * All settings max_freq and min_freq are in terms of radians per sample, - * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian) - * and beta is the frequency gain (second order, units of radians per sample per radian) + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. * \sa gr_pll_refout_cc, gr_pll_carriertracking_cc */ -class GR_CORE_API gr_pll_freqdet_cf : public gr_sync_block +class GR_CORE_API gr_pll_freqdet_cf : public gr_sync_block, public gri_control_loop { - friend GR_CORE_API gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, - float max_freq, float min_freq); + friend GR_CORE_API gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw, + float max_freq, + float min_freq); - float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq; - gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq); + float mod_2pi (float in); + gr_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq); int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); private: - float mod_2pi (float in); float phase_detector(gr_complex sample,float ref_phase); }; diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i index b730f037a..f93e6e37e 100644 --- a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i +++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,11 +22,12 @@ GR_SWIG_BLOCK_MAGIC(gr,pll_freqdet_cf) - gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, - float max_freq, float min_freq); + gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw, + float max_freq, + float min_freq); -class gr_pll_freqdet_cf : public gr_sync_block +class gr_pll_freqdet_cf : public gr_sync_block, public gri_control_loop { private: - gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq); + gr_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq); }; diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc index 8968cd3f1..2b480fcf1 100644 --- a/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc +++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc @@ -30,7 +30,9 @@ #include <math.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw, float max_freq, float min_freq) diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.h b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h index 11bce5046..dcbeb1efa 100644 --- a/gnuradio-core/src/lib/general/gr_pll_refout_cc.h +++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h @@ -43,8 +43,8 @@ GR_CORE_API gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw, * aligned to it. * * All settings max_freq and min_freq are in terms of radians per sample, - * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian) - * and beta is the frequency gain (second order, units of radians per sample per radian) + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc */ class GR_CORE_API gr_pll_refout_cc : public gr_sync_block, public gri_control_loop diff --git a/gnuradio-core/src/lib/general/gri_control_loop.cc b/gnuradio-core/src/lib/general/gri_control_loop.cc index caad1f5f9..4c64bb922 100644 --- a/gnuradio-core/src/lib/general/gri_control_loop.cc +++ b/gnuradio-core/src/lib/general/gri_control_loop.cc @@ -74,9 +74,9 @@ void gri_control_loop::frequency_limit() { if (d_freq > d_max_freq) - d_freq = d_min_freq; + d_freq = d_max_freq; else if (d_freq < d_min_freq) - d_freq = d_max_freq; + d_freq = d_min_freq; } /******************************************************************* diff --git a/gnuradio-core/src/lib/general/qa_general.cc b/gnuradio-core/src/lib/general/qa_general.cc index 6984d798c..b9080f362 100644 --- a/gnuradio-core/src/lib/general/qa_general.cc +++ b/gnuradio-core/src/lib/general/qa_general.cc @@ -28,6 +28,7 @@ #include <qa_general.h> #include <qa_gr_firdes.h> #include <qa_gr_circular_file.h> +#include <qa_gr_cpm.h> #include <qa_gr_fxpt.h> #include <qa_gr_fxpt_nco.h> #include <qa_gr_fxpt_vco.h> @@ -41,6 +42,7 @@ qa_general::suite () s->addTest (qa_gr_firdes::suite ()); s->addTest (qa_gr_circular_file::suite ()); + s->addTest (qa_gr_cpm::suite ()); s->addTest (qa_gr_fxpt::suite ()); s->addTest (qa_gr_fxpt_nco::suite ()); s->addTest (qa_gr_fxpt_vco::suite ()); diff --git a/gnuradio-core/src/lib/general/qa_gr_cpm.cc b/gnuradio-core/src/lib/general/qa_gr_cpm.cc new file mode 100644 index 000000000..cc32d1117 --- /dev/null +++ b/gnuradio-core/src/lib/general/qa_gr_cpm.cc @@ -0,0 +1,140 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <qa_gr_cpm.h> +#include <gr_cpm.h> +#include <cppunit/TestAssert.h> + +const double DELTA = 1e-5; +const int L = 5; +const int samples_per_sym = 4; +const float taps_lrc[20] = { + 0, 0.002447174185242, 0.009549150281253, 0.020610737385376, + 0.034549150281253, 0.050000000000000, 0.065450849718747, 0.079389262614624, + 0.090450849718747, 0.097552825814758, 0.100000000000000, 0.097552825814758, + 0.090450849718747, 0.079389262614624, 0.065450849718747, 0.050000000000000, + 0.034549150281253, 0.020610737385376, 0.009549150281253, 0.002447174185242 +}; + + +const float taps_lsrc[20] = { // beta = 0.2 + 0.000000000000000, 0.009062686687436, 0.019517618142920, 0.030875041875917, + 0.042552315421249, 0.053912556756416, 0.064308860403517, 0.073130584159352, + 0.079847961304114, 0.084051371489937, 0.085482007518284, 0.084051371489937, + 0.079847961304114, 0.073130584159352, 0.064308860403517, 0.053912556756416, + 0.042552315421249, 0.030875041875917, 0.019517618142920, 0.009062686687436 +}; + + +const float taps_tfm[20] = { + -0.003946522220317, -0.005147757690530, -0.003171631690177, 0.003959659609805, + 0.017498721302356, 0.037346982678383, 0.062251889790391, 0.087364237065604, + 0.110049050955117, 0.125677762224511, 0.132288693729399, 0.125677762224511, + 0.110049050955117, 0.087364237065604, 0.062251889790391, 0.037346982678383, + 0.017498721302356, 0.003959659609805, -0.003171631690177, -0.005147757690530 +}; + + +const float taps_gaussian[20] = { // BT = 0.3 + 0.000000743866524, 0.000009286258371, 0.000085441834550, 0.000581664421923, + 0.002945540765422, 0.011178079812344, 0.032117220937421, 0.070841188736816, + 0.122053715366673, 0.167389736919915, 0.185594670675172, 0.167389736919915, + 0.122053715366673, 0.070841188736816, 0.032117220937421, 0.011178079812344, + 0.002945540765422, 0.000581664421923, 0.000085441834550, 0.000009286258371 +}; + + +// Check LREC phase response +void +qa_gr_cpm::t1 () +{ + std::vector<float> taps(gr_cpm::phase_response(gr_cpm::LREC, samples_per_sym, L)); + + for (int i = 0; i < L * samples_per_sym; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], 0.05, DELTA); + } +} + + +// Check LRC phase response +void +qa_gr_cpm::t2 () +{ + std::vector<float> taps(gr_cpm::phase_response(gr_cpm::LRC, samples_per_sym, L)); + float sum = 0; + + for (int i = 0; i < L * samples_per_sym; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_lrc[i], DELTA); + sum += taps[i]; + } + + CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA); +} + + +// Check LSRC phase response +void +qa_gr_cpm::t3 () +{ + std::vector<float> taps(gr_cpm::phase_response(gr_cpm::LSRC, samples_per_sym, L, 0.2)); + float sum = 0; + + for (int i = 0; i < L * samples_per_sym; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_lsrc[i], DELTA); + sum += taps[i]; + } + + CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA); +} + + +// Check the TFM phase response +void +qa_gr_cpm::t4 () +{ + std::vector<float> taps(gr_cpm::phase_response(gr_cpm::TFM, samples_per_sym, L)); + float sum = 0; + + for (int i = 0; i < L * samples_per_sym; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_tfm[i], DELTA); + sum += taps[i]; + } + + CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA); +} + + +// Check the Gaussian phase response +void +qa_gr_cpm::t5 () +{ + std::vector<float> taps(gr_cpm::phase_response(gr_cpm::GAUSSIAN, samples_per_sym, L, 0.3)); + float sum = 0; + + for (int i = 0; i < L * samples_per_sym; i++) { + CPPUNIT_ASSERT_DOUBLES_EQUAL(taps[i], taps_gaussian[i], DELTA); + sum += taps[i]; + } + + CPPUNIT_ASSERT_DOUBLES_EQUAL(sum, 1.0, DELTA); +} + diff --git a/gnuradio-core/src/lib/general/qa_gr_cpm.h b/gnuradio-core/src/lib/general/qa_gr_cpm.h new file mode 100644 index 000000000..741cb2860 --- /dev/null +++ b/gnuradio-core/src/lib/general/qa_gr_cpm.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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 _QA_GR_CPM_H +#define _QA_GR_CPM_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +class qa_gr_cpm : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE (qa_gr_cpm); + CPPUNIT_TEST (t1); + CPPUNIT_TEST (t2); + CPPUNIT_TEST (t3); + CPPUNIT_TEST (t4); + CPPUNIT_TEST (t5); + CPPUNIT_TEST_SUITE_END (); + + private: + void t1 (); + void t2 (); + void t3 (); + void t4 (); + void t5 (); + +}; + + +#endif /* _QA_GR_CPM_H */ + diff --git a/gnuradio-core/src/lib/hier/Makefile.am b/gnuradio-core/src/lib/hier/Makefile.am index b525d19b4..369feef75 100644 --- a/gnuradio-core/src/lib/hier/Makefile.am +++ b/gnuradio-core/src/lib/hier/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2009 Free Software Foundation, Inc. +# Copyright 2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # diff --git a/gnuradio-core/src/lib/hier/hier.i b/gnuradio-core/src/lib/hier/hier.i index dbcc8e915..bec3de7ed 100644 --- a/gnuradio-core/src/lib/hier/hier.i +++ b/gnuradio-core/src/lib/hier/hier.i @@ -29,3 +29,4 @@ %} %include "gr_channel_model.i" + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py index 8e4a0eefa..4c12924ec 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010 Free Software Foundation, Inc. +# Copyright 2004,2007,2010,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,117 +32,116 @@ class test_pll_carriertracking (gr_unittest.TestCase): self.tb = None def test_pll_carriertracking (self): - expected_result = ((1.00000238419+6.47922693275e-09j), - (0.998399555683+0.0565364062786j), - (0.994261980057+0.10695001483j), - (0.98843306303+0.151648163795j), - (0.981579363346+0.191063538194j), - (0.974212288857+0.225630432367j), - (0.966734290123+0.255773901939j), - (0.959442555904+0.281897842884j), - (0.952551782131+0.304379671812j), - (0.946205317974+0.323566257954j), - (0.940503358841+0.339778244495j), - (0.935505151749+0.353307723999j), - (0.931235432625+0.364419162273j), - (0.927616357803+0.373535633087j), - (0.924710214138+0.380666583776j), - (0.922494113445+0.386005342007j), - (0.92093116045+0.389725029469j), - (0.919974088669+0.391981720924j), - (0.919572234154+0.392916500568j), - (0.919680893421+0.392660915852j), - (0.920248389244+0.39133310318j), - (0.921222627163+0.389039844275j), - (0.922548472881+0.385877460241j), - (0.924184799194+0.381939411163j), - (0.926086127758+0.377309292555j), - (0.928135097027+0.37224984169j), - (0.930293083191+0.366814315319j), - (0.932614028454+0.360868781805j), - (0.935064375401+0.354473829269j), - (0.937613248825+0.347684770823j), - (0.940225422382+0.340550601482j), - (0.942881464958+0.33312189579j), - (0.945559620857+0.325443327427j), - (0.948240220547+0.31755694747j), - (0.950899422169+0.309499144554j), - (0.953524827957+0.301307469606j), - (0.956105649471+0.293015599251j), - (0.958630502224+0.284654557705j), - (0.96103054285+0.276443749666j), - (0.963361799717+0.26819768548j), - (0.965623259544+0.259936869144j), - (0.967810571194+0.251679092646j), - (0.969916880131+0.243440493941j), - (0.971936583519+0.235235646367j), - (0.97387367487+0.227080151439j), - (0.975726902485+0.218987599015j), - (0.977494239807+0.210969462991j), - (0.979169845581+0.203035995364j), - (0.980761289597+0.195199295878j), - (0.982269346714+0.187469303608j), - (0.983659446239+0.180052131414j), - (0.984931468964+0.1729388237j), - (0.986136198044+0.165923252702j), - (0.987275123596+0.159012272954j), - (0.988349795341+0.15221118927j), - (0.989354014397+0.145524248481j), - (0.990296065807+0.138957872987j), - (0.991178870201+0.132516458631j), - (0.992005050182+0.126204773784j), - (0.992770493031+0.120025672019j), - (0.993480443954+0.113984130323j), - (0.994139909744+0.108083210886j), - (0.994751393795+0.102326385677j), - (0.995293080807+0.0969148278236j), - (0.995791256428+0.091630294919j), - (0.996252119541+0.0864710733294j), - (0.996678769588+0.0814334899187j), - (0.997069239616+0.0765165910125j), - (0.997423350811+0.071716658771j), - (0.997748315334+0.0670333206654j), - (0.998046517372+0.0624645166099j), - (0.998317599297+0.058009263128j), - (0.998557567596+0.053665690124j), - (0.998775064945+0.0494344644248j), - (0.998971700668+0.0453144386411j), - (0.999140620232+0.0415064357221j), - (0.99927687645+0.0379924885929j), - (0.999400436878+0.0345549099147j), - (0.999511957169+0.0311931278557j), - (0.99961233139+0.0279070306569j), - (0.999694347382+0.0246965941042j), - (0.999765276909+0.0215622838587j), - (0.999826848507+0.0185046810657j), - (0.999880313873+0.0155246723443j), - (0.999920129776+0.0126227736473j), - (0.999949812889+0.00980060640723j), - (0.99997317791+0.00705910893157j), - (0.999990820885+0.00439921114594j), - (0.999998450279+0.00202245195396j), - (0.999998092651-0.00029227725463j), - (0.999994516373-0.00254815118387j), - (0.999988794327-0.00474932929501j), - (0.999977111816-0.00689708162099j), - (0.999957799911-0.00899503659457j), - (0.999936699867-0.0110441967845j), - (0.999914228916-0.0130464555696j), - (0.999889075756-0.0150024276227j), - (0.999855577946-0.0169130507857j), - (0.999821305275-0.0187777336687j), - (0.999786794186-0.0205969288945j)) + expected_result = ((1.00000238419+6.57831922268e-09j), + (0.998351693153+0.0573740489781j), + (0.994012773037+0.109242096543j), + (0.987789511681+0.155784770846j), + (0.980356454849+0.197242289782j), + (0.972262203693+0.233890414238j), + (0.963963091373+0.266027569771j), + (0.955816328526+0.293958544731j), + (0.948096513748+0.31798568368j), + (0.941002130508+0.338400006294j), + (0.934680581093+0.355482578278j), + (0.929229319096+0.369498342276j), + (0.924701035023+0.380694836378j), + (0.921043872833+0.389459967613j), + (0.918319702148+0.395834594965j), + (0.91650646925+0.400014132261j), + (0.915561556816+0.40217769146j), + (0.915425121784+0.402490824461j), + (0.916029334068+0.401106894016j), + (0.917308092117+0.39817237854j), + (0.919185698032+0.393822491169j), + (0.921583771706+0.388183712959j), + (0.924419641495+0.381372988224j), + (0.927624821663+0.373506993055j), + (0.93112629652+0.364693939686j), + (0.934793651104+0.355197936296j), + (0.938562095165+0.345107495785j), + (0.942447602749+0.33434677124j), + (0.946396291256+0.323003143072j), + (0.950359642506+0.311159342527j), + (0.954286515713+0.298890888691j), + (0.958144724369+0.286276459694j), + (0.961902141571+0.273387700319j), + (0.96553081274+0.260292351246j), + (0.969001471996+0.247053653002j), + (0.972298383713+0.233733415604j), + (0.975410103798+0.220389455557j), + (0.978325486183+0.207074314356j), + (0.981000483036+0.194007188082j), + (0.983471632004+0.181051760912j), + (0.985742926598+0.168245732784j), + (0.987816333771+0.155622571707j), + (0.989693164825+0.143212914467j), + (0.991374969482+0.131043404341j), + (0.992875099182+0.119139909744j), + (0.994201719761+0.107524067163j), + (0.995362222195+0.0962148010731j), + (0.996359944344+0.0852287560701j), + (0.997212648392+0.0745811164379j), + (0.997930467129+0.0642844736576j), + (0.998514950275+0.0545224510133j), + (0.998972594738+0.0452938191593j), + (0.999334216118+0.0364210158587j), + (0.99960911274+0.0279066264629j), + (0.999806642532+0.0197515785694j), + (0.99992787838+0.0119558870792j), + (0.999987542629+0.00451827049255j), + (0.999994814396-0.00256353616714j), + (0.999957740307-0.00929233431816j), + (0.999877095222-0.0156717002392j), + (0.999762177467-0.0217055380344j), + (0.999622702599-0.0273993015289j), + (0.999463677406-0.0327589809895j), + (0.999292552471-0.0376165211201j), + (0.999108791351-0.0421659946442j), + (0.998919844627-0.0464186370373j), + (0.998729586601-0.0503882467747j), + (0.998537421227-0.0540841519833j), + (0.998342692852-0.0575186908245j), + (0.9981533885-0.0607041418552j), + (0.997971534729-0.063651651144j), + (0.997796595097-0.0663715749979j), + (0.997623920441-0.0688742175698j), + (0.997461974621-0.0711689144373j), + (0.997311413288-0.0732654929161j), + (0.997185945511-0.0749996080995j), + (0.997077047825-0.0763883292675j), + (0.996980309486-0.0776248201728j), + (0.996895432472-0.0787187665701j), + (0.996822297573-0.0796797126532j), + (0.996752738953-0.0805156230927j), + (0.996692657471-0.0812350511551j), + (0.996642947197-0.0818456709385j), + (0.996603965759-0.0823540389538j), + (0.996568918228-0.0827651321888j), + (0.996540248394-0.0830852389336j), + (0.996520996094-0.0833202600479j), + (0.996510386467-0.0834743082523j), + (0.996518313885-0.0833787024021j), + (0.996529102325-0.083223849535j), + (0.996545791626-0.0830176770687j), + (0.99656867981-0.0827698707581j), + (0.996593296528-0.0824855566025j), + (0.99661642313-0.0821713805199j), + (0.996643543243-0.081834435463j), + (0.996674180031-0.0814796686172j), + (0.996706545353-0.0811114609241j), + (0.996734440327-0.0807323306799j), + (0.996764600277-0.0803465023637j), + (0.996797323227-0.0799564495683j)) sampling_freq = 10e3 freq = sampling_freq / 100 - alpha = 0.1 - beta = alpha * alpha / 4.0 + loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0) - pll = gr.pll_carriertracking_cc(alpha, beta, maxf, minf) + pll = gr.pll_carriertracking_cc(loop_bw, maxf, minf) head = gr.head (gr.sizeof_gr_complex, int (freq)) dst = gr.vector_sink_c () diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py index 5225a9a3b..b84299a94 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010 Free Software Foundation, Inc. +# Copyright 2004,2007,2010,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,117 +32,116 @@ class test_pll_freqdet (gr_unittest.TestCase): self.tb = None def test_pll_refout (self): - expected_result = (1.1489677586e-07, - 0.972821060568, - 2.74556447638, - 5.14063078448, - 8.00965819311, - 11.2291393027, - 14.6967068752, - 18.3279143967, - 22.0534772463, - 25.8170093072, - 29.5729107661, - 33.284774699, - 36.923857393, - 40.4367950308, - 43.8452195091, - 47.1363835133, - 50.3011949468, - 53.3336447847, - 56.2301489564, - 58.9891659262, - 61.6107668417, - 64.0962975824, - 66.4481356707, - 68.6694531128, - 70.7640326003, - 72.7048735417, - 74.5033180826, - 76.2012544926, - 77.8019199967, - 79.3088126954, - 80.7255907715, - 82.0560369166, - 83.3039516093, - 84.47312347, - 85.5673411194, - 86.5902864563, - 87.5456117346, - 88.4368565575, - 89.2363918613, - 89.9860999864, - 90.688880206, - 91.3474598523, - 91.9644654653, - 92.5423042123, - 93.0832706099, - 93.5894872344, - 94.0629225081, - 94.5054203452, - 94.9186882929, - 95.3043331057, - 95.6326268597, - 95.9117515522, - 96.1801447842, - 96.437391527, - 96.6831953314, - 96.9173605408, - 97.1397982206, - 97.3504727968, - 97.5493842694, - 97.7366275022, - 97.9123092169, - 98.0766013539, - 98.2297054988, - 98.3408087235, - 98.448722155, - 98.5534457933, - 98.6549322065, - 98.7531932527, - 98.8481459259, - 98.9397487233, - 99.0279067813, - 99.1125074491, - 99.193438076, - 99.2705800823, - 99.3438030304, - 99.3817663128, - 99.3911400359, - 99.4089388448, - 99.4334136894, - 99.4630408207, - 99.4964684305, - 99.5325166512, - 99.5701538394, - 99.6084432158, - 99.6466021546, - 99.6839073198, - 99.7197895289, - 99.7537270313, - 99.7542606398, - 99.7595848672, - 99.7691186729, - 99.7822928746, - 99.7986331535, - 99.8175940432, - 99.838713083, - 99.8614922382, - 99.8854571901, - 99.9101454781, - 99.9351302152, - 99.9599845147) + expected_result = (4.33888922882e-08, + 0.367369994515, + 1.08135249597, + 2.10983253908, + 3.42221529438, + 4.98940390402, + 6.78379190842, + 8.77923286024, + 10.9510106794, + 13.2758363182, + 15.7317829127, + 18.2982902299, + 20.9561068599, + 23.6755271122, + 26.452952094, + 29.2731265301, + 32.1219053479, + 34.9862418188, + 37.8540971414, + 40.7144315483, + 43.5571390869, + 46.3730179743, + 49.1537231663, + 51.8917218889, + 54.58026103, + 57.2015358514, + 59.7513664199, + 62.2380533124, + 64.657612252, + 67.006640002, + 69.2822432184, + 71.4820384499, + 73.6041047056, + 75.6469478817, + 77.6094829742, + 79.4909866472, + 81.2911031615, + 83.0097850853, + 84.6355598352, + 86.1820937186, + 87.6504420946, + 89.0418441206, + 90.3577286819, + 91.5996432431, + 92.7692775646, + 93.8684162704, + 94.8989269904, + 95.8627662892, + 96.7619381633, + 97.598505899, + 98.362769679, + 99.0579904444, + 99.6992633875, + 100.288805948, + 100.828805921, + 101.321421457, + 101.76878699, + 102.17300138, + 102.536116055, + 102.860158727, + 103.147085962, + 103.398830608, + 103.617254366, + 103.792467691, + 103.939387906, + 104.060030865, + 104.15631756, + 104.230085975, + 104.283067372, + 104.316933727, + 104.333238432, + 104.333440018, + 104.318914008, + 104.290941063, + 104.250742554, + 104.187634452, + 104.103822339, + 104.013227468, + 103.916810336, + 103.815448432, + 103.709936239, + 103.600997093, + 103.489283183, + 103.375351833, + 103.259712936, + 103.142828952, + 103.025091195, + 102.90686726, + 102.776726069, + 102.648078982, + 102.521459607, + 102.397294831, + 102.275999684, + 102.157882471, + 102.043215927, + 101.93218978, + 101.824958181, + 101.72159228, + 101.622151366, + 101.526623582) sampling_freq = 10e3 freq = sampling_freq / 100 - alpha = 0.2 - beta = alpha * alpha / 4.0 + loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0) - pll = gr.pll_freqdet_cf(alpha, beta, maxf, minf) + pll = gr.pll_freqdet_cf(loop_bw, maxf, minf) head = gr.head (gr.sizeof_float, int (freq)) dst = gr.vector_sink_f () diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py index c40a885a8..14f9ab877 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py @@ -32,117 +32,116 @@ class test_pll_refout (gr_unittest.TestCase): self.tb = None def test_pll_refout (self): - expected_result = ((1+7.39965699825e-10j), - (0.999980390072+0.00626518437639j), - (0.999828696251+0.0185074284673j), - (0.999342679977+0.0362518876791j), - (0.998255133629+0.0590478181839j), - (0.996255218983+0.0864609107375j), - (0.993005692959+0.118066303432j), - (0.988157629967+0.153442293406j), - (0.981362581253+0.192165210843j), - (0.972283244133+0.233806177974j), - (0.960601866245+0.277928203344j), - (0.946027755737+0.324085712433j), - (0.928303182125+0.371824204922j), - (0.907292485237+0.420500129461j), - (0.882742881775+0.469856351614j), - (0.854515135288+0.519426465034j), - (0.822515428066+0.568742752075j), - (0.786696314812+0.617340147495j), - (0.747057616711+0.664759278297j), - (0.703645646572+0.710551083088j), - (0.656552672386+0.754280209541j), - (0.605915129185+0.795529305935j), - (0.551911592484+0.833902597427j), - (0.494760006666+0.869029641151j), - (0.43471455574+0.900568306446j), - (0.37224894762+0.928132891655j), - (0.30767711997+0.951490819454j), - (0.241136431694+0.970491230488j), - (0.172981828451+0.984925031662j), - (0.103586450219+0.99462044239j), - (0.0333373323083+0.999444127083j), - (-0.0373690575361+0.999301552773j), - (-0.108130030334+0.994136750698j), - (-0.178540825844+0.983932495117j), - (-0.248198583722+0.968709170818j), - (-0.316705673933+0.948523879051j), - (-0.383672952652+0.923469007015j), - (-0.448723316193+0.893670737743j), - (-0.51132196188+0.85938924551j), - (-0.571328520775+0.820721447468j), - (-0.628420114517+0.777874112129j), - (-0.682293117046+0.73107868433j), - (-0.732665538788+0.680588841438j), - (-0.779277384281+0.626679122448j), - (-0.821892917156+0.569642007351j), - (-0.860301196575+0.509786069393j), - (-0.894317150116+0.447433561087j), - (-0.923782229424+0.382918298244j), - (-0.948564887047+0.316582858562j), - (-0.968560874462+0.248776733875j), - (-0.983657121658+0.180051699281j), - (-0.993847966194+0.110753215849j), - (-0.999158322811+0.0410195216537j), - (-0.999585151672-0.0288011860102j), - (-0.995150566101-0.0983632653952j), - (-0.985901713371-0.16732545197j), - (-0.971909940243-0.235353127122j), - (-0.953270018101-0.302119642496j), - (-0.9300994277-0.367307811975j), - (-0.902537107468-0.430612027645j), - (-0.870742559433-0.49173912406j), - (-0.834894418716-0.550410091877j), - (-0.795189499855-0.606360971928j), - (-0.751972675323-0.659194231033j), - (-0.705345034599-0.708864152431j), - (-0.65554022789-0.755160272121j), - (-0.602804005146-0.79788929224j), - (-0.547393083572-0.836875617504j), - (-0.489574223757-0.871961653233j), - (-0.429622590542-0.903008520603j), - (-0.367820799351-0.929896712303j), - (-0.30445766449-0.952525854111j), - (-0.239826664329-0.970815718174j), - (-0.174224823713-0.984705924988j), - (-0.107951194048-0.994156181812j), - (-0.0415063276887-0.999138236046j), - (0.0248276274651-0.999691724777j), - (0.0909758731723-0.995853126049j), - (0.156649470329-0.987654268742j), - (0.221562758088-0.975146114826j), - (0.285434871912-0.958398103714j), - (0.347990810871-0.937497973442j), - (0.408962905407-0.912550985813j), - (0.468091338873-0.883680105209j), - (0.525126338005-0.851024270058j), - (0.57982814312-0.814738810062j), - (0.631968915462-0.77499371767j), - (0.681333422661-0.731973171234j), - (0.727582573891-0.68602013588j), - (0.770699381828-0.637198925018j), - (0.810512244701-0.585721731186j), - (0.846863090992-0.531810998917j), - (0.879608631134-0.475698113441j), - (0.908620357513-0.417623132467j), - (0.933785498142-0.357833325863j), - (0.955007195473-0.296582698822j), - (0.972205162048-0.234130680561j), - (0.985315918922-0.170741200447j), - (0.994293272495-0.106681488454j), - (0.999108314514-0.0422209985554j)) + expected_result = ((1+6.4087357643e-10j), + (0.999985277653+0.00542619498447j), + (0.999868750572+0.0162021834403j), + (0.99948567152+0.0320679470897j), + (0.99860727787+0.0527590736747j), + (0.996953129768+0.0780025869608j), + (0.994203746319+0.107512556016j), + (0.990011692047+0.140985429287j), + (0.984013140202+0.178095817566j), + (0.975838363171+0.218493551016j), + (0.965121984482+0.261800557375j), + (0.95151245594+0.307610183954j), + (0.934681296349+0.355486690998j), + (0.914401650429+0.404808044434j), + (0.890356600285+0.455263823271j), + (0.862329125404+0.506348133087j), + (0.830152392387+0.557536482811j), + (0.793714106083+0.608290970325j), + (0.752960026264+0.658066213131j), + (0.707896590233+0.706316053867j), + (0.658591926098+0.752500295639j), + (0.605175673962+0.796091973782j), + (0.547837555408+0.836584687233j), + (0.48682525754+0.873499393463j), + (0.42244040966+0.906390726566j), + (0.355197101831+0.934791445732j), + (0.285494059324+0.958380460739j), + (0.213591173291+0.976923108101j), + (0.139945343137+0.990159213543j), + (0.065038472414+0.997882783413j), + (-0.0106285437942+0.999943494797j), + (-0.0865436866879+0.996248066425j), + (-0.162189796567+0.986759603024j), + (-0.23705175519+0.971496999264j), + (-0.310622543097+0.950533330441j), + (-0.38240903616+0.923993110657j), + (-0.451937526464+0.89204955101j), + (-0.518758952618+0.854920566082j), + (-0.582311093807+0.812966048717j), + (-0.642372369766+0.76639264822j), + (-0.698591887951+0.715520322323j), + (-0.750654160976+0.660695314407j), + (-0.798280358315+0.602286040783j), + (-0.841228663921+0.540679454803j), + (-0.87929558754+0.476276367903j), + (-0.912315964699+0.409486919641j), + (-0.940161883831+0.340728074312j), + (-0.962742805481+0.270418733358j), + (-0.980004072189+0.198977485299j), + (-0.991925954819+0.126818284392j), + (-0.99851256609+0.0545223206282j), + (-0.999846458435-0.0175215266645j), + (-0.996021270752-0.0891158208251j), + (-0.987133920193-0.159895718098j), + (-0.973306238651-0.2295101583j), + (-0.954683184624-0.297624111176j), + (-0.931430280209-0.363919824362j), + (-0.903732538223-0.428097635508j), + (-0.871792256832-0.489875763655j), + (-0.835827112198-0.548992812634j), + (-0.796068251133-0.605206847191j), + (-0.752758979797-0.658296227455j), + (-0.706152498722-0.70805978775j), + (-0.656641483307-0.754202902317j), + (-0.604367733002-0.79670548439j), + (-0.549597978592-0.835429251194j), + (-0.492602348328-0.870254516602j), + (-0.433654457331-0.901079237461j), + (-0.373029649258-0.927819430828j), + (-0.31100410223-0.950408577919j), + (-0.247853919864-0.968797445297j), + (-0.183855071664-0.982953369617j), + (-0.119282215834-0.992860376835j), + (-0.0544078871608-0.998518764973j), + (0.0104992967099-0.999944865704j), + (0.0749994292855-0.997183561325j), + (0.138844624162-0.990314185619j), + (0.201967850327-0.979392170906j), + (0.264124274254-0.964488625526j), + (0.325075358152-0.945688128471j), + (0.3845885396-0.92308807373j), + (0.442438393831-0.89679890871j), + (0.498407125473-0.866943061352j), + (0.552284479141-0.833655714989j), + (0.603869199753-0.797083437443j), + (0.652970373631-0.757383465767j), + (0.69940674305-0.714723825455j), + (0.743007957935-0.66928255558j), + (0.78350687027-0.62138313055j), + (0.820889055729-0.571087777615j), + (0.855021059513-0.51859331131j), + (0.885780930519-0.46410369873j), + (0.913058102131-0.407829582691j), + (0.936754107475-0.349988251925j), + (0.956783294678-0.290801793337j), + (0.973072886467-0.230497643352j), + (0.985563337803-0.169307261705j), + (0.9942086339-0.1074674353j), + (0.9989772439-0.0452152714133j), + (0.999851942062+0.0172088555992j)) sampling_freq = 10e3 freq = sampling_freq / 100 - alpha = 0.1 - beta = alpha * alpha / 4.0 + loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0) - pll = gr.pll_refout_cc(alpha, beta, maxf, minf) + pll = gr.pll_refout_cc(loop_bw, maxf, minf) head = gr.head (gr.sizeof_gr_complex, int (freq)) dst = gr.vector_sink_c () @@ -151,8 +150,7 @@ class test_pll_refout (gr_unittest.TestCase): self.tb.run () dst_data = dst.data () - - self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5) + self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 4) if __name__ == '__main__': gr_unittest.run(test_pll_refout, "test_pll_refout.xml") |