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

📄 chest_rcv.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
📖 第 1 页 / 共 2 页
字号:
  swr_fft_complex( f_inv, logb( f_len ), SWR_FFT );  for ( i=0; i<f_len; i++ ){    f_inv[i] = pow(2,24)/f_inv[i];  }  swr_fft_complex( f_inv, logb( f_len ), SWR_IFFT );  f_max = 1;  for ( i=0; i<f_len; i++ ){    f_abs += cabs( f_inv[i] );    f_max = max( cabs( f_inv[i] ), (double)f_max );  }  for ( i=0; i<f_len; i++ ){    f_inv[i] /= f_max;    // filter_inv is just for displaying the filter    channel_inv[i].real = creal( f_inv[i] ) * 32767;    channel_inv[i].imag = cimag( f_inv[i] ) * 32767;    if ( i < 5 ){      PR_DBG_CL( 5, "%i: %i/%i\n", i, 		 channel_inv[i].real, channel_inv[i].imag );    }  }  f_abs /= f_max;  /******************Noise Variance Calculation Begins***************    noise1 = receivedvalue1 - h11*s1 - h12*s2 - h13s3 - h14s4 etc..         var(noise) = sum( noise ^ 2) - mean( noise )^2      Flat channel is assumed! Hence every 'L'the element starting at 0     of filter is the channel coefficient.    We are to calculate the variance of a complex noise variable.    We assume independent and equal components, hence we calculate     only the variance of the real component.  ******************************************************************/  //Mid points to the received midamble  mid            = in + data_len[0];  channel_offset = training_seq[ type ].L; //Channel Length  length         = 2 * training_seq[ type ].Nt;  for ( i = 0; i < training_seq[ type ].Nt; i++) {    //real_term = channel[0].real * seq[ 2*i ]  - channel[0].imag * seq[ 2*i + 1 ];    real_term = 0;    imag_term = 0;    for ( j = 0; j < num_of_antennas; j++) {      //Careful with cyclic shifts      seq_offset = training_seq[ type ].Nt - j * channel_offset;      real_term += channel[ j * channel_offset ].real * 	seq[ ( 2 * ( i + seq_offset) ) % length] -	channel[ j * channel_offset ].imag *	seq[ ( 2 * ( i + seq_offset) + 1 ) % length];            imag_term += channel[ j * channel_offset ].imag * 	seq[ ( 2 * ( i + seq_offset) ) % length] +	channel[ j * channel_offset ].real *	seq[ ( 2 * ( i + seq_offset) + 1 ) % length];    }        noise_term_real     += mid[ i ].real - real_term;    noise_term_imag     += mid[ i ].imag - imag_term;    var_noise_term_real += ( mid[ i ].real - real_term ) *       (mid[ i ].real - real_term);    var_noise_term_imag += ( mid[ i ].imag - imag_term ) *       (mid[ i ].imag - imag_term);        PR_DBG( 4, "in module var_noise:(%g,%g) mid.real:%i, real:%i\n", 	    var_noise_term_real, var_noise_term_imag,	    mid[i].real, real_term );  }  noise_term_real = noise_term_real / training_seq[ type ].Nt;  noise_term_real = noise_term_real * noise_term_real;  noise_term_imag = noise_term_imag / training_seq[ type ].Nt;  noise_term_imag = noise_term_imag * noise_term_imag;    noise_var_real = var_noise_term_real / training_seq[type].Nt - noise_term_real;  noise_var_imag = var_noise_term_imag / training_seq[type].Nt - noise_term_imag;  noise_var =  noise_var_real + noise_var_imag;   PR_DBG( 2, "in module noise_Var_real = %i, noise_var_imag = %i \n", 	  noise_var_real, noise_var_imag );  for ( i=0; i<num_of_antennas; i++ ){    j = training_seq[ type ].L * i;    PR_DBG( 2, "h[%i] = %i + %ii\n", i, channel[ j ].real, channel[ j ].imag );  }  /******************Noise Variance Calculation Ends******************/    sig_power = 0.;  for( i = 0; i < size_in(0);i++){    sig_power += in[i].real * in[i].real + in[i].imag * in[i].imag;  }  sig_power /= size_in(0);  //sig_power -= noise_var;   // Search for the peak in the midamble  peak_pos = 0;  peak_amp = 0;  mid_amp = 0;  for ( i=0; i<training_seq[ type ].L; i++ ){    int pos = i + private->index * training_seq[ type ].L;    mid_amp += hypot( channel[pos].real, channel[pos].imag );    if ( hypot( channel[pos].real, channel[pos].imag ) > peak_amp ){      peak_pos = pos;      peak_amp = hypot( channel[pos].real, channel[pos].imag );    }  }  mid_amp /= training_seq[ type ].L;  mid_amp *= mid_amp;  // Copy the data as-is, but perhaps shifted  PR_DBG( 4, "f Peak_position : %i\n", peak_pos );  if ( private->align ){    PR_DBG( 2, "Found maximum filter at %i\n", peak_pos );    if ( !private->calc_taps ){      in += ( peak_pos % training_seq[ type ].L ) - circ_ext;    }    peak_pos -= circ_ext;  }  /**   * If calc_taps is > 0, then we calculate a matched filter with length   * calc_taps   */  if ( private->calc_taps > 0 ){    complex double *f = f_inv + s_row - 1;    double m_amp = 0, nv = 0;    int train_len = training_seq[ type ].Nt;    SYMBOL_COMPLEX *matched_mid = private->mid,      *mid_seq = (SYMBOL_COMPLEX*)seq;    // First we search for the peak, so that we do the convolution with the    // right data    peak_pos = 0;    peak_amp = 0;    for ( i=0; i<MAX_NO_OF_ANT*MAX_NO_OF_TAPS; i++ ){      if ( cabs( f_inv[ i ] ) > peak_amp ){	peak_pos = i;	peak_amp = cabs( f_inv[ i ] );      }    }    peak_pos = MAX_NO_OF_ANT*MAX_NO_OF_TAPS - peak_pos - 1;    mid = in + data_len[0] + circ_ext + peak_pos;    for ( i=0; i<MAX_NO_OF_ANT*MAX_NO_OF_TAPS; i++ ){      if ( cabs( SC_TO_CD( mid[i] ) ) > m_amp ){	m_amp = cabs( SC_TO_CD( mid[i] ) );      }    }    f_abs *= m_amp / 16000.;        in -= circ_ext - 1;    if ( private->align ){      // Make sure we won't get out of the filter      int diff = max( 0, peak_pos - private->calc_taps / 2 );      in += diff;      f -= diff;    }    PR_DBG( 4, "f_inv Peak_position : %i\n", peak_pos );    // Do a matched filtering    // For the first half of the data    do_mafi( in, out, f, f_abs, private->calc_taps, data_len[0] );    // For the second half of the data    do_mafi( in + data_len[0] + train_len + circ_ext,	     out + data_len[0], 	     f, f_abs, private->calc_taps, data_len[1] );    // Calculate the matched filter of the training sequence    do_mafi( in + data_len[0] + circ_ext,	     matched_mid,	     f, f_abs, private->calc_taps, train_len );    // Do something with matched_mid    //    matched_mid[0:train_len-1 ] <->    //mid_seq[0:train_len-1];    // to check if the received midamble corresponds to the    // tranmsitted one    for ( i = 0; i < train_len; i++) {      PR_DBG( 4, "Tx_mid, Rx_mid: %i %i\n", mid_seq[i].imag,	      matched_mid[i].imag );    }        // compute the mid_amp    for ( i = 0; i < train_len; i++){      tmp +=  (int)mid_seq[i].real * (int)matched_mid[i].real +	(int)mid_seq[i].imag * (int)matched_mid[i].imag;    }    if ( tmp > 0 ){      mid_amp = (int)(tmp/train_len);    } else {      mid_amp = 1;    }    // calculate the noise variance    for ( i = 0; i < train_len; i++){      int re, im;      re = matched_mid[i].real - mid_amp * mid_seq[i].real;      im = matched_mid[i].imag - mid_amp * mid_seq[i].imag;      nv += re * re + im * im;    }    noise_var = nv / train_len;      } else {    int train_len = training_seq[ type ].Nt;    //Copy the first data stream to out    memcpy( out, in, data_len[0] * sizeof( SYMBOL_COMPLEX ) );    //Copy the second data stream to out    PR_DBG( 4, "Offset is: %i\n", data_len[0] + train_len + circ_ext );    memcpy( out + data_len[0],	    in + data_len[0] + train_len + circ_ext,	    data_len[1] * sizeof( SYMBOL_COMPLEX ) );  }  swr_sdb_get_stats_struct( context->id, (void**)&stats );  stats->noise_var      = noise_var;  stats->noise_var_real = noise_var_real;  stats->noise_var_imag = noise_var_imag;  stats->ch_length      = channel_offset;  if ( ( mid_amp > 0 ) && ( noise_var > 0 ) ){    stats->snr          = 10 * (log10(mid_amp)*2 - log10(noise_var) );   } else {    stats->snr          = -20;  }  stats->peak_pos       = peak_pos;  stats->peak_amp       = peak_amp;  stats->mid_amp        = mid_amp;  swr_sdb_free_stats_struct( context->id, (void**)&stats );  return(0);}/* int rcv_custom( swr_sdb_t *context *//* * This is the `destructor'. */int rcv_finalize( swr_sdb_t *context ) {  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;  /**   * 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, 6, 11 );  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,POINTER}( "name" );   * UM_STATS_{INT,DOUBLE,STRING128,POINTER,BLOCK}( "name" );   */  UM_CONFIG_INT( "type" );  UM_CONFIG_INT( "num_of_antennas" );  UM_CONFIG_INT( "calc_taps" );  UM_CONFIG_INT( "align" );  UM_CONFIG_INT( "index" );  UM_CONFIG_INT( "circ_ext" );  UM_STATS_BLOCK( "channel" );  UM_STATS_BLOCK( "channel_inv" );  UM_STATS_BLOCK( "midamble" );  UM_STATS_DOUBLE( "snr" );  UM_STATS_INT( "noise_var" );  UM_STATS_INT( "noise_var_real" );  UM_STATS_INT( "noise_var_imag" );  UM_STATS_INT( "ch_length" );  UM_STATS_INT( "peak_pos" );  UM_STATS_INT( "peak_amp" );  UM_STATS_INT( "mid_amp" );    /**   * 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_SYMBOL_COMPLEX, 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. Change the name!  rcv_id = swr_cdb_register_spc( &desc, "chest_rcv" );  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 + -