www.pudn.com > wimax_ofdm_implementation_code.rar > pseudo_channel.c


/*****************************************************************************/
/*   FIle Name : pseudo_channel.c                                            */
/*   Description : Wi-Max SC Pseudo Channel Estimatitor                      */
/*                 mode : [3]  1:step 0:bilinear interpolation               */
/*                      : [1:0]  0:drift both in freq & time domain          */
/*                      : [1:0]  1:drift only in freq_domain                 */
/*                 multi : number of multiple paths                          */
/*                 level : White Noise level 0:-120dB@peak 6:-114dB...120:0dB*/
/*                 tx_freqerr : Transmitter's Frequency error                */
/*                            : 0:0ppm 1:0.01ppm -10:-0.1ppm(-0.1<=f<=0.1ppm)*/
/*                 rx_freqerr : Receiver's Frequency error                   */
/*                            : 0:0ppm 1:0.01ppm -10:-0.1ppm(-0.1<=f<=0.1ppm)*/
/*   author : miffie                                                         */
/*   Date   : oct/20/05                                                      */
/*   Copyright (c) 2005 miffie   All rights reserved.                        */
/*****************************************************************************/
//In Wi-MAX SC the SS's clock is locked to BS. 
//And only allowed 1ppm of clock frequecny error.

struct complexset pseudo_channel(struct complexset datain, 
                                char mode, char multi, char level,
                                char tx_freqerr, char rx_freqerr ) { 
int 	ii,kk ;
int 	size ;
int     tmp0 ;
int     startpoint ;
double  tx_clock, rx_clock ;
double  tx_carrierclock, rx_carrierclock ;
double  tx_phase, rx_phase ;
double  rx_time ;
struct 	complex  *top ;
struct 	complex  *cdata ;
struct 	complex  tmp1, tmp2 , tmp3;
int     tx_floor , tx_ceil ;
struct  complexset  ctop ;
double  white ;
char    NO_NOISE = 0 ;
static  double   sample_period = 125 ; //ns //8MHz
static  double   carrier_period = 0.1 ; //ns //10GHz
static  int      delay = 60 ; //ns


   PRINTF("pseudo_channel size=%d multi=%d level=%d tx_freqerr=%d rx_freqerr=%d\n", 
          datain.size , multi, level, tx_freqerr, rx_freqerr) ;
   if (mode<4) { //doubler
     tx_clock = (sample_period/2.0)*(1.0+(tx_freqerr/100000000.0)) ; //ns
     rx_clock = (sample_period)*(1.0+(rx_freqerr/100000000.0)) ; //ns
     size = (datain.size/2) +32 ; //+32 for extention
   } //doubler
   else { //single
     tx_clock = (sample_period)*(1.0+(tx_freqerr/100000000.0)) ; //ns
     rx_clock = (sample_period)*(1.0+(rx_freqerr/100000000.0)) ; //ns
     size = datain.size +32 ; //+32 for extention
   } //single
   tx_carrierclock = carrier_period*(1.0+(tx_freqerr/100000000.0)) ; //ns 
   rx_carrierclock = carrier_period*(1.0+(rx_freqerr/100000000.0)) ; //ns 

   //noises
   NO_NOISE = (multi==0) && (level==0) ; //if 1  NO Noise
   white = pow(2, ((double)level-120.0)/6.0) ; //WhiteNoiseGain
   
   //sampling clock width 
   if (((top = (struct complex *)malloc(size*sizeof(struct complex)) ) == NULL) |
       ((cdata = (struct complex *)malloc((datain.size+200)*sizeof(struct complex)) ) == NULL)){
        PRINTF( " malloc failed in pseudo_channel.c\n") ;
   } //fail
   else { //allocated
     //initialize
     for( ii=0;ii=1) rx_time += delay - gamma_random(delay)  ;
        } //NO_NOISE

        //rotation
        if(kk==0) { //first path's gain is fixed
           tmp3.realp = 1.0 ;
           tmp3.image = 0 ;
        } else { //second path and beyond
          tmp3.realp = ((double)int_random(8)+8)/32.0 ;
          tmp3.image = ((double)int_random(8)+8)/32.0 ;
          tmp3.realp = (int_random(2)) ? -tmp3.realp : tmp3.realp ;
          tmp3.image = (int_random(2)) ? -tmp3.image : tmp3.image ;
        }
        printf("rx_time %8.5f r=%8.5f i=%8.5f\n" , rx_time , tmp3.realp , tmp3.image) ;
   
        for( ii=0;ii