⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atsci_sssr.cc

📁 这是用python语言写的一个数字广播的信号处理工具包。利用它
💻 CC
字号:
/* -*- c++ -*- *//* * Copyright 2002,2008 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 <atsci_sssr.h>#include <algorithm>#include <cmath>#include <cstdio>#include <assert.h>#include <atsci_diag_output.h>#include <gr_math.h>#include <stdio.h>/* * ---------------------------------------------------------------- * Segment Integrator Pre-Processor * * Compute weight passed to integrator based on * correlation result and ncorr_gain2 */inline static intsipp (bool digcorr_output){  if (digcorr_output)    return +2;			// positive correlation  else    return -1;			// no correlation}/*  * ---------------------------------------------------------------- * Segment Sync Integrator... */static const int SSI_MIN = -16;static const int SSI_MAX =  15;voidsssr::seg_sync_integrator::reset (){  for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++)    d_integrator[i] = SSI_MIN;}  intsssr::seg_sync_integrator::update (int weight, int index){  int	t = d_integrator[index] + weight;  t = std::max (t, SSI_MIN);  t = std::min (t, SSI_MAX);  d_integrator[index] = t;  return t;}intsssr::seg_sync_integrator::find_max (int *v){  int	best_value = d_integrator[0];  int	best_index = 0;    for (int i = 1; i < ATSC_DATA_SEGMENT_LENGTH; i++)    if (d_integrator[i] > best_value){      best_value = d_integrator[i];      best_index = i;    }  *v = best_value;  return best_index;}/* * ---------------------------------------------------------------- * Segment Sync and Symbol recovery */static const int	SYMBOL_INDEX_OFFSET = 3;static const int	MIN_SEG_LOCK_CORRELATION_VALUE = 5;atsci_sssr::atsci_sssr ()  : d_debug_fp(0){  reset ();    if (_SSSR_DIAG_OUTPUT_){    const char *file = "sssr.ssout";    if ((d_debug_fp = fopen (file, "wb")) == 0){      perror (file);      exit (1);    }  }}atsci_sssr::~atsci_sssr (){  if (d_debug_fp)    fclose (d_debug_fp);}voidatsci_sssr::reset (){  d_correlator.reset ();  d_integrator.reset ();  d_quad_filter.reset ();  for (int i = 0; i < ATSC_DATA_SEGMENT_LENGTH; i++)    d_quad_output[i] = 0;    d_timing_adjust = 0;  d_counter = 0;  d_symbol_index = 0;  d_seg_locked = false;}voidatsci_sssr::update (sssr::sample_t sample_in,	 // input		   bool		 *seg_locked,	 // are we seeing segment syncs?		   int		 *symbol_index,	 // 0..831		   double	 *timing_adjust) // how much to adjust timing{  double qo = d_quad_filter.update (sample_in);  d_quad_output[d_counter] = qo;  int bit = gr_signbit (sample_in) ^ 1;	// slice on sign: + => 1, - => 0  int corr_out = d_correlator.update (bit);  int weight = sipp (corr_out);  int corr_value = d_integrator.update (weight, d_counter);  int best_correlation_index = -1;  incr_symbol_index ();  if (incr_counter ()){		// counter just wrapped...    int	best_correlation_value;    best_correlation_index = d_integrator.find_max (&best_correlation_value);    d_seg_locked = best_correlation_value >= MIN_SEG_LOCK_CORRELATION_VALUE;    d_timing_adjust = d_quad_output[best_correlation_index];    d_symbol_index = SYMBOL_INDEX_OFFSET - 1 - best_correlation_index;    if (d_symbol_index < 0)      d_symbol_index += ATSC_DATA_SEGMENT_LENGTH;  }  *seg_locked = d_seg_locked;  *symbol_index = d_symbol_index;  *timing_adjust = d_timing_adjust;  if (_SSSR_DIAG_OUTPUT_){    float	iodata[7];    iodata[0] = bit;    iodata[1] = corr_value;    iodata[2] = qo;    iodata[3] = d_counter;    iodata[4] = d_symbol_index;    iodata[5] = best_correlation_index;    iodata[6] = d_timing_adjust;    if (fwrite (iodata, sizeof (iodata), 1, d_debug_fp) != 1){      perror ("fwrite: sssr");      exit (1);    }  }}/* * ---------------------------------------------------------------- * Interpolator control for Seg & Symbol Sync Recovery */static const double	LOOP_FILTER_TAP = 0.00025;	// 0.0005 worksstatic const double	ADJUSTMENT_GAIN = 1.0e-5 / (10 * ATSC_DATA_SEGMENT_LENGTH);  atsci_interpolator::atsci_interpolator (double nominal_ratio_of_rx_clock_to_symbol_freq)  : d_debug_fp(0){// Tweaked ratio from 1.8 to 1.78 to support input rate of 19.2MHz  assert (nominal_ratio_of_rx_clock_to_symbol_freq >= 1.78);  d_nominal_ratio_of_rx_clock_to_symbol_freq =    nominal_ratio_of_rx_clock_to_symbol_freq;  d_loop.set_taps (LOOP_FILTER_TAP);  reset ();  if (_SSSR_DIAG_OUTPUT_){    const char *file = "interp.ssout";    if ((d_debug_fp = fopen (file, "wb")) == 0){      perror (file);      exit (1);    }  }}atsci_interpolator::~atsci_interpolator (){  if (d_debug_fp)    fclose (d_debug_fp);}voidatsci_interpolator::reset (){  d_w = d_nominal_ratio_of_rx_clock_to_symbol_freq;  d_mu = 0.5;  d_incr = 0;  d_loop.reset ();}boolatsci_interpolator::update (	   const sssr::sample_t input_samples[],	// I: vector of samples	   int	     		nsamples,		// I: total number of samples	   int	    	       *index,			// I/O: current input index	   double     		timing_adjustment,	// I: how much to bump timing	   sssr::sample_t      *output_sample){  if (*index + (int) ntaps () > nsamples)    return false;  // FIXME Confirm that this is right.  I think it is.  It was (1-d_mu)  *output_sample = d_interp.interpolate (&input_samples[*index], d_mu);    double filter_out = 0;  #if 0  filter_out = d_loop.filter (timing_adjustment);  d_w = d_w + ADJUSTMENT_GAIN * filter_out * 1e-3;#elif 1  filter_out = d_loop.filter (timing_adjustment);  d_mu = d_mu + ADJUSTMENT_GAIN * 10e3 * filter_out;#else  static const double alpha = 0.01;  static const double beta = alpha * alpha / 16;  double x = ADJUSTMENT_GAIN * 10e3 * timing_adjustment;  d_mu = d_mu + alpha * x;	// conceptually "phase"  d_w  = d_w  + beta * x;	// conceptually "frequency"  #endif    double s = d_mu + d_w;  double float_incr = floor (s);  d_mu = s - float_incr;  d_incr = (int) float_incr;  assert (d_incr >= 1 && d_incr <= 3);  *index += d_incr;  if (_SSSR_DIAG_OUTPUT_){    float	iodata[6];    iodata[0] = timing_adjustment;    iodata[1] = filter_out;    iodata[2] = d_w;    iodata[3] = d_mu;    iodata[4] = d_incr;    iodata[5] = *output_sample;    if (fwrite (iodata, sizeof (iodata), 1, d_debug_fp) != 1){      perror ("fwrite: interpolate");      exit (1);    }  }  return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -