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

📄 midamble_rcv.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
📖 第 1 页 / 共 2 页
字号:
  // TODO: Use this Nicolae-function over all possible indexes  // giving peak_amp[0]..peak_amp[max_index-1]  {    //int re, im, sq;    peak_amp = 0;    stats_offset = 0;    mid_amp_old =0;    for ( i=0; i<private->est.estimation_length; i++ ) {      re = est->matched_filter_Re[i];      im = est->matched_filter_Im[i];      sq = re * re + im * im;      mid_amp_old +=sq;      if ( sq > peak_amp ) {        peak_amp = sq;        stats_offset = i;        com_p.real = re;        com_p.imag = im;      }      private->mafi[i].real = re;      private->mafi[i].imag = im;    }  }  peak_amp = sqrt( peak_amp );  /*  // TODO: print all amplitudes  // define peak_amp as array of integer and define max_index  // Put peak_amp as array of integer into the stats  PR_DBG( 4, "Amplitudes for the indexes: " );  for ( i=0; i<max_index; i++ ){    PR_DBG_CL( 4, "peak_amp[%i]=%i  ", i, peak_amp[i] );  }  PR_DBG( 4, "Peak_Amp: %i, offset: %i, data_len: %i:%i, data_pos: %i:%i, est:%i\n",   peak_amp, stats_offset,   data_len_half, data_len_half, data_pos[0], data_pos[1],   est->estimation_length );  */  // Matched filtering on the data is only done for the  // index given in the configuration  // Now extract symbols from data fields using matched filters  // beginning of the first  data field  data_pos[0] = 0;  // beginning of the second data field  data_pos[1] = ( slc + mid_length ) / 2;  // is the length of the 1st and 2nd data field  data_len_half = ( slc - mid_length ) / 2;  x += data_pos[0];  matched_filtering(x,                    (mmx_t*)est->matched_filter_Re,                    (mmx_t*)est->matched_filter_Im,                    out,                    est->estimation_length,                    DAQ_SAMPLES_PER_CHIP,                    data_len_half );  x += data_pos[1] - data_pos[0];  matched_filtering(x,                    (mmx_t *)est->matched_filter_Re,                    (mmx_t *)est->matched_filter_Im,                    &out[data_len_half],                    est->estimation_length,                    DAQ_SAMPLES_PER_CHIP,                    data_len_half );  // Filter the midamble  mid_rx=swr_malloc(mid_length*sizeof(SYMBOL_COMPLEX));  mid_tx=swr_malloc(mid_length*sizeof(SYMBOL_COMPLEX));  x += mid_start - data_pos[1] - m->shift;  matched_filtering(x,                    (mmx_t *)est->matched_filter_Re,                    (mmx_t *)est->matched_filter_Im,                    mid_rx,                    est->estimation_length,                    DAQ_SAMPLES_PER_CHIP,                    mid_length );  // Take the mean midamble-amplitude  memset( private->midamble, 0, sizeof( private->midamble ) );  midamble_write( type, mid_tx, 1, index );  tmp = 0.;  for(i=0; i<mid_length; i++) {    tmp += (int)mid_rx[i].real * (int)mid_tx[i].real +           (int)mid_rx[i].imag * (int)mid_tx[i].imag;    private->midamble[i] = mid_rx[i];  }  if ( tmp >= mid_length ) {    mid_amp = (int)( tmp / mid_length );  } else {    PR_DBG( 2, "tmp < mid_length: %s%i.%i\n", swr_ftosii( tmp ) );    for(i=0; i<mid_length; i++) {      PR_DBG( 4, "%6i,%6i\n",              (int)mid_rx[i].real * (int)mid_tx[i].real,              (int)mid_rx[i].imag * (int)mid_tx[i].imag );    }    mid_amp = 1;  }  midamble_write( type, mid_tx, mid_amp, index );  // Calculate the variance  noise_var = 0.;  mean_re = mean_im = 0;  flip_prob = 0.0;  for(i=0; i<mid_length; i++) {    int re, im;    re = mid_rx[i].real - mid_tx[i].real;    im = mid_rx[i].imag - mid_tx[i].imag;    mean_re += re;    mean_im += im;    noise_var += re * re + im * im;    if(mid_rx[i].real * mid_tx[i].real < 0)      flip_prob ++;    if(mid_rx[i].imag * mid_tx[i].imag < 0)      flip_prob ++;  }  noise_var /= mid_length;  // Calculate the variance the old way  // The number 82252 relates the midamble_amplitude to the energy  // of the matched-filter. As this number is composed of the factors  // noise, A/D resolution and length of the matched filter, it is  // only correct for a certain SNR value. Especially for low SNR this  // number is completely bogus!  mid_amp_old /= 82252;  noise_var_old = 0.;  midamble_write( type, mid_tx, mid_amp_old, index );  for(i=0; i<mid_length; i++) {    int re, im;    re = mid_rx[i].real - mid_tx[i].real;    im = mid_rx[i].imag - mid_tx[i].imag;    noise_var_old += re * re + im * im;  }  noise_var_old /= mid_length;  flip_prob /= (2 * mid_length);  mean_re /= mid_length;  mean_im /= mid_length;  PR_DBG( 4, "len: %i, mid_amp:%i, peak:%5i, "          "n_var:%s%i.%i, mean_re:%i, mean_im:%i, flip_prob:%f\n",          private->est.estimation_length, mid_amp, peak_amp,          swr_ftosii( noise_var ), mean_re, mean_im, flip_prob );  for(i=0; i<2; i++) {    PR_DBG(4, "mid_tx[%2i]=(%6i,%6i) mid_rx[%2i]=(%6i,%6i) out[%2i]=(%6i,%6i)\n",           i, mid_tx[i].real, mid_tx[i].imag, i, mid_rx[i].real, mid_rx[i].imag,           i, out[i].real, out[i].imag );  }  swr_free( mid_rx );  swr_free( mid_tx );  // Calculate the snr_data  data_amp = 0.;  for ( i=0; i < 2 * data_len_half; i++ ){    data_amp += out[i].real * out[i].real +      out[i].imag * out[i].imag;  }  data_amp /= 2 * data_len_half;  // And save the statistic parameters.  swr_sdb_get_stats_struct( context->id, (void**)&stats );  stats->peak = com_p;  stats->peak_amp = peak_amp;  stats->mid_amp = mid_amp;  stats->noise_var = noise_var;  stats->flip_prob = max( flip_prob, (double)1e-3 );  stats->midamble.size = mid_length;  if ( ( mid_amp <= 0 ) || ( noise_var <= 0 ) ) {    PR_DBG( 2*0, "mid_amp: %i, noise_var: %s%i.%i\n",            mid_amp, swr_ftosii( noise_var ) );  } else {    stats->snr_mid = stats->snr =       10 * ( log10( mid_amp )*2 - log10( noise_var ) );  }  if ( ( data_amp <= 0 ) || ( noise_var <= 0 ) ||       ( data_amp / noise_var - 1 <= 0 ) ) {    PR_DBG( 2, "data_amp: %s%i.%i, noise_var: %s%i.%i\n",            swr_ftosii( data_amp ), swr_ftosii( noise_var ) );    stats->snr = 0;  } else {    stats->snr_data = 10 * ( log10( data_amp / noise_var - 1 ) );  }  // This is the old way of calculating the midamble-amplitude and the snr  stats->noise_var_old = noise_var_old;  stats->mid_amp_old = mid_amp_old;  if ( ( mid_amp_old <= 0 ) || ( noise_var_old <= 0 ) ) {    PR_DBG( 2, "mid_amp_old: %i, noise_var_old: %s%i.%i\n",            mid_amp_old, swr_ftosii( noise_var_old ) );  } else {    stats->snr_old = 10 * ( log10( mid_amp_old )*2 - log10( noise_var_old ) );  }  if ( private->gain_control ) {    if ( peak_amp < private->gain_control ) {      //private->rx_gain += max( 1, ( private->gain_control - peak_amp ) / 10 );      private->rx_gain += 1;      swr_ant_set_gain_rx( private->antenna, private->rx_gain );    } else {      private->rx_gain -= 1;      swr_ant_set_gain_rx( private->antenna, private->rx_gain );    }  }  for (i = 0; i < MAX_CH_EST; i++) {    stats->peak_amp_stat[i] = private->peak_amp_stat[i];  }  swr_sdb_get_config_struct( context->id, (void**)&config );  // This offset can be added directly to the 'final' offset  stats->offset = ( stats_offset - config->peak_location ) / 4;  swr_sdb_free_config_struct( context->id, (void**)&config );  swr_sdb_free_stats_struct( context->id, (void**)&stats );  PR_DBG( 4, "Exiting\n" );  return(0);}/* * This is the `destructor'. */int rcv_finalize( swr_sdb_t *context ) {  stats_t *stats;  swr_sdb_get_stats_struct( context->id, (void**)&stats );  stats->mafi.data = 0;  swr_sdb_free_stats_struct( context->id, (void**)&stats );  if ( sizeof( private_t ) > 0 )    swr_free( private );  MOD_DEC_USE_COUNT;  return 0;}/* * This function is called upon "insmod" and is used to register the * different parts of the module to the SPM. */swr_spc_id_t rcv_id;int rcv_module_init(void) {  swr_spc_desc_t *desc;  char str[256];  int i;  /**   * Get a description-part from SPM   * Give the following parameters:   * Input-ports, output-ports, config-params, stat-params   */  desc = swr_spc_get_new_desc( 1, 1, 5, ( 14 + MAX_CH_EST ) );  if ( !desc ) {    PR_DBG( 0, "Can't initialise the module. This is BAD!\n" );    return -1;  }  /**   * Define the different parts of config and stats. You have to define   * them in the same order as they appear in the structures. The names   * can be freely chosen.   *   * UM_CONFIG_{INT,DOUBLE,STRING128}( "name" );   * UM_STATS_{INT,DOUBLE,STRING128}( "name" );   */  UM_CONFIG_INT( "type", PARAMETER_DEBUG );  UM_CONFIG_INT( "index" );  UM_CONFIG_INT( "peak_location", PARAMETER_DEBUG );  UM_CONFIG_INT( "gain_control" );  UM_CONFIG_INT( "num_ch_est", PARAMETER_DEBUG );  UM_STATS_DOUBLE( "snr_mid" );  UM_STATS_DOUBLE( "snr_data" );  UM_STATS_INT( "peak_amp", PARAMETER_DEBUG );  UM_STATS_INT( "offset" );  UM_STATS_INT( "mid_amp" );  UM_STATS_INT( "mid_amp_old", PARAMETER_DEBUG );  UM_STATS_INT( "noise_var" );  UM_STATS_INT( "noise_var_old", PARAMETER_DEBUG );  UM_STATS_DOUBLE( "flip_prob" );  UM_STATS_DOUBLE( "snr_old", PARAMETER_DEBUG );  UM_STATS_BLOCK( "mafi" );  UM_STATS_BLOCK( "midamble" );  UM_STATS_COMPLEX( "peak", PARAMETER_DEBUG );  for ( i = 0; i<MAX_CH_EST ; i++ ) {    sprintf( str, "peak_amp_stat%02i", i );    UM_STATS_INT( str, PARAMETER_DEBUG );  }  UM_STATS_DOUBLE( "snr", PARAMETER_DEBUG );  /**   * The in- and outputs have also to be defined in the right order. First   * port first. The additional flag is not used yet, but it will...   *   * UM_INPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 );   * UM_OUTPUT( SIG_{U8,SYMBOL_{S16,COMPLEX,MMX},SAMPLE_S12,S32}, 0 );   */  UM_INPUT( SIG_SAMPLE_S12, 0 );  UM_OUTPUT( SIG_SYMBOL_COMPLEX, 0 );  // Initialise the callback-functions. Delete the ones you don't use  desc->fn_init              = rcv_init;  desc->fn_reconfigure       = rcv_reconfig;  desc->fn_process_data      = rcv_pdata;  desc->fn_configure_inputs  = rcv_configure_inputs;  desc->fn_configure_outputs = rcv_configure_outputs;  desc->fn_finalize          = rcv_finalize;  // And register the module in the SPM.  rcv_id = swr_cdb_register_spc( &desc, "matched_filter" );  if ( rcv_id == SWR_SPM_INVALID_ID ) {    swr_spc_free_desc( desc );    PR_DBG( 0, "Couldn't register the module!\n" );    return 1;  }  PR_DBG( 4, "Ready\n" );  return 0;}/* * This is called upon rmmod */void rcv_module_exit( void ) {  PR_DBG( 4, "Freeing id: %i\n", rcv_id );  if ( swr_cdb_unregister_spc( rcv_id ) < 0 ) {    PR_DBG( 0, "Still in use somewhere\n" );  }}

⌨️ 快捷键说明

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