four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
core/simulator.cpp
00001 //
00002 // Copyright 2011-2013, Per Zetterberg, KTH Royal Institute of Technology
00003 //
00004 // This program is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 
00019 #include "simulator.hpp"
00020 #include "four_multi.hpp"
00021 #include <itpp/itbase.h>
00022 #include <itpp/base/itfile.h>
00023 #include <itpp/itsignal.h>
00024 #include <ctime>
00025 
00026 
00027 using namespace itpp;
00028 
00040 void simulate(std::vector<four_multi_node*> *nodes,channel_model *c){
00041   std::vector<four_multi_node*> cnodes;
00042   cnodes=*nodes;
00043   frame_settings next_frame;
00044   frame_settings next_frame_all[nodes->size()];
00045   frame_settings next_next_frame_all[nodes->size()];
00046   std::complex<int16_t> *pr; // Pointers to receive buffers.
00047   std::complex<int16_t> *pt; // Pointers to transmit buffers.
00048   double gain_tx, gain_rx, f_tx, f_rx;
00049   uint32_t no_ant_tx, no_ant_rx;
00050   uint32_t buffer_length;
00051   bool all_are_done;
00052   void* feedback_buffers[(nodes->size())*(nodes->size())];
00053   bool feedback_buffers_empty[(nodes->size())*(nodes->size())];
00054   uint32_t num_nodes;
00055 
00056   num_nodes=nodes->size();
00057 
00058 
00059   #if 0
00060   buffer_length=cnodes[0]->d_buffer_length;
00061   for (uint32_t node_counter=1;node_counter<nodes->size();node_counter++){
00062     if (!(buffer_length==cnodes[node_counter]->d_buffer_length)) {
00063       std::cout << "All nodes must have the same buffer length \n";
00064       exit(1);
00065     }
00066   };
00067   #endif
00068 
00069 
00070   for (uint32_t node_counter1=0;node_counter1<nodes->size();node_counter1++){
00071       for (uint32_t node_counter2=0;node_counter2<nodes->size();node_counter2++){
00072         cnodes[node_counter1]->d_simulate=true;
00073         //feedback_buffers_empty[node_counter1+num_nodes*node_counter2]=new bool;
00074         feedback_buffers_empty[node_counter1+num_nodes*node_counter2]=true;
00075       };
00076   };
00077 
00078 
00079   for (uint32_t node_counter=0;node_counter<nodes->size();node_counter++){
00080         cnodes[node_counter]->feedback_buffers=feedback_buffers;
00081         cnodes[node_counter]->feedback_buffers_empty=feedback_buffers_empty;
00082         cnodes[node_counter]->num_nodes=num_nodes;
00083   };
00084 
00085  
00086   for (uint32_t node_counter=0;node_counter<nodes->size();node_counter++){
00087      next_frame=cnodes[node_counter]->node_init();     
00088      while (IS_CALIB_BURST(next_frame)) {
00089        next_frame=cnodes[node_counter]->node_process();
00090      };
00091      next_frame_all[node_counter]=next_frame;
00092   };
00093 
00094 
00095   all_are_done=true;
00096   for (uint32_t node_counter=0;node_counter<nodes->size();node_counter++){
00097     next_frame=next_frame_all[node_counter];
00098     if (!(next_frame.what==END))
00099       all_are_done=false;
00100   };
00101   
00102 
00103 
00104   while (!all_are_done) {
00105 
00106 
00107     std::cout << "================================================ \n";
00108 
00109     double time;
00110 
00111     uint32_t node_counter0;
00112     for (node_counter0=0;node_counter0<nodes->size();node_counter0++){
00113       if (!(next_frame_all[node_counter0].what==END)) {
00114         time=(double) next_frame_all[node_counter0].time.get_real_secs();
00115         break;
00116       }
00117     };
00118     for (uint32_t node_counter=node_counter0;node_counter<nodes->size();node_counter++){
00119 
00120       if (!(next_frame_all[node_counter].what==END)) {
00121         
00122         if (!(time==(double) next_frame_all[node_counter].time.get_real_secs())) {
00123           std::cout << "All nodes must have the same frame times \n";
00124         exit(1);
00125         };
00126       };
00127     };
00128 
00129 
00130     std::cout << "time=" << time << "\n";
00131 
00132 
00133 
00134     for (uint32_t node_rx=0;node_rx<nodes->size();node_rx++){
00135       no_ant_rx=cnodes[node_rx]->d_no_ant1+cnodes[node_rx]->d_no_ant2;
00136 
00137       
00138       if (next_frame_all[node_rx].what==RX) {
00139 
00140         for (uint32_t i1=0;i1<no_ant_rx;i1++) {
00141 
00142           if (i1<next_frame_all[node_rx].frequency.size()) {
00143             f_rx=next_frame_all[node_rx].frequency[i1];
00144           } else {
00145             f_rx=next_frame_all[node_rx].frequency.back();
00146           };
00147          
00148           
00149           if (i1<next_frame_all[node_rx].gain_rx.size()) {
00150             gain_rx=next_frame_all[node_rx].gain_rx[i1];
00151           }
00152           else {
00153             gain_rx=next_frame_all[node_rx].gain_rx.back();
00154           };
00155 
00156 
00157           pr=(std::complex<short int>*)(cnodes[node_rx]->d_rx_buffers[i1]);
00158           for (uint32_t i2=0;i2<cnodes[node_rx]->d_buffer_length;i2++) {
00159             pr[i2]=0;
00160           };      
00161 
00162           for (uint32_t node_tx=0;node_tx<nodes->size();node_tx++){
00163 
00164 
00165             if (next_frame_all[node_tx].what==TX) {
00166 
00167               
00168               no_ant_tx=cnodes[node_tx]->d_no_ant1+cnodes[node_tx]->d_no_ant2;
00169 
00170               for (uint32_t i2=0;i2<no_ant_tx;i2++) {
00171 
00172 
00173                 if (i2<next_frame_all[node_tx].frequency.size())
00174                   f_tx=next_frame_all[node_tx].frequency[i2];
00175                 else
00176                   f_tx=next_frame_all[node_tx].frequency.back();                
00177                                
00178                 if (i2<next_frame_all[node_tx].gain_tx.size())
00179                   gain_tx=next_frame_all[node_tx].gain_tx[i2];
00180                 else
00181                   gain_tx=next_frame_all[node_tx].gain_tx.back();
00182 
00183                 
00184                 pt=(std::complex<short int>*) cnodes[node_tx]->d_tx_buffers[i2];                
00185 
00186                 buffer_length=cnodes[node_tx]->d_buffer_length;
00187                 if ((cnodes[node_rx]->d_buffer_length)<buffer_length)
00188                   buffer_length=cnodes[node_rx]->d_buffer_length;
00189 
00190                 c->sub_channel(node_tx,node_rx,i2,i1,f_tx,f_rx,time,gain_tx,
00191                                gain_rx,pt,pr,buffer_length);
00192               };   
00193             };
00194           };
00195           // Add noise
00196           buffer_length=cnodes[node_rx]->d_buffer_length;
00197           c->add_noise(gain_rx,pr,buffer_length);
00198         };       
00199         // Process the received data at the receivers
00200 
00201         if (cnodes[node_rx]->save_input_on_file) {
00202           cnodes[node_rx]->log_raw_buffer(cnodes[0]->d_buffer_length);
00203         };     
00204         next_frame=cnodes[node_rx]->node_process();
00205         next_next_frame_all[node_rx]=next_frame;
00206       }; 
00207       
00208     };
00209 
00210 
00211     // Do all the transmitters
00212     for (uint32_t node_tx=0;node_tx<nodes->size();node_tx++){
00213       if (next_frame_all[node_tx].what==TX) {   
00214         next_frame=cnodes[node_tx]->node_process();
00215         next_next_frame_all[node_tx]=next_frame;
00216      };
00217     };
00218 
00219 
00220     // Those who have ended
00221     for (uint32_t node_tx=0;node_tx<nodes->size();node_tx++){
00222       if (next_frame_all[node_tx].what==END) {
00223         next_next_frame_all[node_tx].what=END;
00224       };
00225     };
00226  
00227 
00228     for (uint32_t node_counter=0;node_counter<nodes->size();node_counter++){
00229       next_frame_all[node_counter]=next_next_frame_all[node_counter];
00230     };
00231 
00232 
00233 
00234     all_are_done=true;
00235     for (uint32_t node_counter=0;node_counter<nodes->size();node_counter++){
00236       next_frame=next_frame_all[node_counter];
00237       if (!(next_frame.what==END))
00238         all_are_done=false;
00239      };
00240     
00241 
00242   };
00243   for (uint32_t node_ix=0;node_ix<nodes->size();node_ix++){
00244     if (cnodes[node_ix]->save_input_on_file) {
00245       cnodes[node_ix]->save_logged_raw_data();
00246     };  
00247     cnodes[node_ix]->end_of_run();
00248   };
00249   std::cout << "Simulation done! \n";
00250 
00251 };
00252 
00253 void block_fading::sub_channel(uint32_t from_node_ix
00254 ,uint32_t to_node_ix, uint32_t from_antenna_ix,  uint32_t to_antenna_ix,
00255 double freq_tx, double freq_rx,  double time, double gain_tx, double gain_rx, 
00256                   std::complex<short int> const* signal_in, std::complex<short int>* signal_out,uint32_t number_of_samples)
00257 {
00258 
00259 
00260   // Save the old seed and create a random
00261   ivec seed_state;
00262   RNG_get_state(seed_state);
00263   if (seed==0)
00264     RNG_randomize();
00265   else {
00266     RNG_reset(seed);
00267     seed++;
00268   };
00269   // Randomize a single coefficient
00270   std::complex<double> h;
00271   itpp::cvec s_in, s_out;
00272   
00273   // Set length of ITPP vectors
00274   s_in.set_length(number_of_samples);
00275   s_out.set_length(number_of_samples);
00276 
00277   // Convert input to cvec
00278   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00279     s_in[i1]=signal_in[i1];
00280   };
00281 
00282   // Convert receiver buffer to cvec
00283   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00284     s_out[i1]=signal_out[i1];
00285   };
00286 
00287 
00288   // Do the channel model
00289   mat temp;
00290   double t;
00291   temp=old_time[from_node_ix][to_node_ix];
00292   t=temp.get(from_antenna_ix,to_antenna_ix);
00293 
00294   for (uint32_t i3=0;i3<num_of_taps;i3++) {
00295 
00296     if (time>t) {
00297       h=itpp::randn_c();
00298       h=forgetting_factor*(old_h[from_node_ix][to_node_ix][i3]).
00299         get(from_antenna_ix,to_antenna_ix)+
00300       sqrt(1-forgetting_factor*forgetting_factor)*h;
00301      old_h[from_node_ix][to_node_ix][i3].set(from_antenna_ix,to_antenna_ix,h);
00302     } else {
00303       h=(old_h[from_node_ix][to_node_ix][i3]).get(from_antenna_ix,                                                to_antenna_ix);
00304     };
00305 
00306     if (is_awgn) {
00307       if (i3==0)
00308         h=1;
00309       else
00310         h=0;
00311     };
00312     if (is_diagonal) {
00313       if (from_antenna_ix!=to_antenna_ix)  {
00314         h=0; 
00315       };
00316     };
00317  
00318     h=path_gain[from_node_ix][to_node_ix]*scaling_signal*h;
00319     h=h/sqrt(num_of_taps);
00320     for (int i4=i3;i4<s_in.length();i4++) {
00321       s_out(i4)+=h*s_in(i4-i3);
00322     };
00323   };
00324   // Convert output to  std::complex<short int>
00325   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00326     signal_out[i1]=s_out[i1];
00327   };
00328   
00329   // Reset the seed
00330   RNG_set_state(seed_state);
00331 
00332 };
00333 
00334 void block_fading::add_noise(double gain_rx, 
00335         std::complex<short int>* signal, 
00336                                  uint32_t number_of_samples) {
00337 
00338   itpp::cvec s, n;
00339 
00340   // Save the old seed and create a random
00341   ivec seed_state;
00342   RNG_get_state(seed_state);
00343   RNG_randomize();
00344 
00345 
00346   // Set length of ITPP vectors
00347   s.set_length(number_of_samples);
00348 
00349   // Convert input to cvec
00350   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00351     s[i1]=signal[i1];
00352   };
00353 
00354   // Generate noise
00355   n=itpp::randn_c(number_of_samples);
00356   n=scaling_noise*n;
00357 
00358 
00359   // Add noise
00360   s=s+n;
00361 
00362   // Convert output to  std::complex<short int>
00363   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00364      signal[i1]=s[i1];
00365   };
00366 
00367   // Reset the seed
00368   RNG_set_state(seed_state);
00369 
00370   
00371 
00372 }
00373 
00374 block_fading::block_fading(void) {
00375 
00376   scaling_signal=0.45;
00377   scaling_noise=4.5;//21.7;
00378   seed=0;
00379   forgetting_factor=0.0;
00380   is_awgn=false;
00381   is_diagonal=false;
00382   num_of_taps=1;
00383   // Save the old seed and create a random
00384   ivec seed_state;
00385   RNG_get_state(seed_state);
00386   if (seed==0)
00387     RNG_randomize();
00388   else {
00389     RNG_reset(seed);
00390     seed=seed+1;
00391   };
00392 
00393 
00394   for (uint32_t i1=0;i1<max_num_nodes;i1++) {
00395     for (uint32_t i2=0;i2<max_num_nodes;i2++) {
00396       old_time[i1][i2].set_size(max_num_ant,max_num_ant);
00397       old_time[i1][i2].zeros();
00398       path_gain[i1][i2]=1.0;
00399       for (uint32_t i3=0;i3<max_num_taps;i3++) {
00400         old_h[i1][i2][i3].set_size(max_num_ant,max_num_ant);
00401         old_h[i1][i2][i3]=randn_c(max_num_ant,max_num_ant);
00402       };
00403     };
00404   };
00405   // Reset the seed
00406   RNG_set_state(seed_state);
00407 
00408 
00409 };
00410 
00411 void block_fading::reset(void) {
00412 
00413   ivec seed_state;
00414 
00415   RNG_get_state(seed_state);
00416   if (seed==0)
00417     RNG_randomize();
00418   else {
00419     RNG_reset(seed);
00420     seed++;
00421   };
00422 
00423   for (uint32_t i1=0;i1<max_num_nodes;i1++) {
00424     for (uint32_t i2=0;i2<max_num_nodes;i2++) {
00425       old_time[i1][i2].zeros();
00426       for (uint32_t i3=0;i3<max_num_taps;i3++) {        
00427         old_h[i1][i2][i3]=randn_c(max_num_ant,max_num_ant);
00428       };
00429     };
00430   };
00431 
00432   //std::cout << "old_h=" << old_h[0][0][0](0,0) << "\n";
00433 
00434   // Reset the seed
00435   RNG_set_state(seed_state);
00436 
00437 
00438 };
00439 
00440 from_file::from_file(std::string directory_name) {
00441   raw_data_dir=directory_name;
00442   for (uint32_t i1=0;i1<max_num_nodes;i1++) {
00443     for (uint32_t i2=0;i2<max_num_nodes;i2++) {
00444       old_time[i1][i2].set_size(max_num_ant,max_num_ant);
00445       old_time[i1][i2]=-ones(max_num_ant,max_num_ant);
00446       frame_ix[i1][i2].set_size(max_num_ant,max_num_ant);
00447       frame_ix[i1][i2]=-ones_i(max_num_ant,max_num_ant);
00448 
00449     };
00450   };
00451 };
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 void from_file::sub_channel(uint32_t from_node_ix,uint32_t to_node_ix, 
00460                          uint32_t from_antenna_ix, uint32_t to_antenna_ix 
00461                             , double freq_tx, double freq_rx,
00462                                  double time, double gain_tx, double gain_rx, 
00463                             std::complex<short int> const* signal_in, std::complex<short int>* signal_out,uint32_t number_of_samples) {
00464 
00465 
00466   mat temp;
00467   double t;
00468   int f_ix;
00469   std::string filename;
00470   std::stringstream temp_ss;
00471   std::ifstream s1; 
00472 
00473   temp=old_time[from_node_ix][to_node_ix];
00474   t=temp.get(from_antenna_ix,to_antenna_ix);
00475 
00476   f_ix=frame_ix[from_node_ix][to_node_ix](from_antenna_ix,to_antenna_ix);
00477 
00478   if (time>t) {
00479     f_ix++;
00480     (frame_ix[from_node_ix][to_node_ix])(from_antenna_ix,to_antenna_ix)=f_ix;
00481     (old_time[from_node_ix][to_node_ix])(from_antenna_ix,to_antenna_ix)=time;
00482   };
00483 
00484   temp_ss << to_node_ix;
00485   filename=raw_data_dir+"node="+temp_ss.str()+"_";
00486   temp_ss.str("");
00487   temp_ss << f_ix;
00488   filename+="frame="+temp_ss.str()+".dat";
00489   temp_ss.str("");
00490   //std::cout << "filename=" << filename << std::endl;
00491 
00492   s1.open(filename.c_str(), std::ios::binary);
00493   for (uint32_t i1=0;i1<to_antenna_ix+1;i1++) {
00494     s1.read((char *) signal_out,number_of_samples*4); 
00495   };
00496   s1.close(); 
00497 
00498   
00499 };
00500 
00501 OFDM_channel_from_file::OFDM_channel_from_file(std::string filename,
00502 ivec num_ant,int Nfft,int Nc, 
00503              ivec ix_all ,int tx_start_sample, int rx_start_sample,
00504             double signal_scaling, double EVM,double EVM_RX, double CPE) {
00505 
00506   d_EVM=EVM;
00507   d_EVM_RX=EVM_RX;
00508   d_CPE=CPE;
00509   d_filename=filename;
00510   d_num_ant=num_ant;
00511   d_num_nodes=d_num_ant.length();
00512   d_Nfft=Nfft;
00513   d_signal_scaling=signal_scaling;
00514   d_Nc=Nc;
00515   d_tx_start_sample=tx_start_sample;
00516   d_rx_start_sample=rx_start_sample;
00517   d_frame_ix=0;
00518   t_old=0;
00519   d_ix_all=ix_all;
00520   counter=0;
00521   rand_cpe.set_size(max_num_ant,max_num_nodes);
00522 
00523   for (int i1=0;i1<d_num_nodes;i1++) {
00524     for (int i2=0;i2<d_num_nodes;i2++) {
00525       for (int i3=0;i3<d_num_ant(i1);i3++) {
00526         (H[i1][i2][i3]).set_size(d_num_ant(i2),ix_all.length());
00527       };
00528     };
00529   };
00530 
00531 
00532   std::stringstream temp_ss;
00533   temp_ss << d_frame_ix;  
00534   load_file(d_filename+"_frame_ix="+temp_ss.str()+".dat");
00535 
00536 };
00537 
00538 void OFDM_channel_from_file::reset(void) {
00539   d_frame_ix=0;
00540   t_old=0;
00541   counter=0;
00542   std::stringstream temp_ss;
00543   temp_ss << d_frame_ix;  
00544   load_file(d_filename+"_frame_ix="+temp_ss.str()+".dat");
00545 };
00546 
00547 void OFDM_channel_from_file::load_file(std::string filename) {
00548 
00549 
00550  std::ifstream s1;   
00551  s1.open(filename.c_str(), std::ios::binary);
00552  double r,i;
00553  
00554  for (int i2=0;i2<d_num_nodes;i2++) {
00555    for (int i1=0;i1<d_num_nodes;i1++) {
00556      
00557 
00558     for (int i5=0;i5<d_ix_all.length();i5++) { 
00559       for (int i4=0;i4<d_num_ant(i1);i4++) {
00560          for (int i3=0;i3<d_num_ant(i2);i3++) {  
00561            
00562 
00563            s1.read((char *) &r,sizeof(double));
00564            real(H[i1][i2][i4](i3,i5))=r;
00565 
00566            
00567            
00568          };
00569        };
00570      };
00571 
00572 
00573     for (int i5=0;i5<d_ix_all.length();i5++) { 
00574       for (int i4=0;i4<d_num_ant(i1);i4++) {
00575          for (int i3=0;i3<d_num_ant(i2);i3++) {  
00576            s1.read((char *) &i,sizeof(double));
00577            imag(H[i1][i2][i4](i3,i5))=i;
00578 
00579          };
00580        };
00581      };
00582 
00583    };
00584  };
00585  s1.close();
00586 
00587  double x,y;
00588  vec tempn;
00589  //rand_cpe=d_CPE*randn(max_num_ant,max_num_nodes);
00590  for (int i1=0;i1<(int) max_num_ant;i1++) {
00591    for (int i2=0;i2<(int) max_num_nodes;i2++) {
00592      tempn=randu(2);
00593      x=tempn(0);
00594      if (x<0.5)
00595        y=(1/sqrt(2))*log(2.0*x);
00596      else
00597        y=(1/sqrt(2))*log(2.0*(1-x));
00598 
00599      if (x>0.5){
00600        y=-y;
00601      };     
00602      rand_cpe(i1,i2)=d_CPE*y;
00603    };
00604  };
00605 
00606 
00607 };
00608 
00609 
00610 void OFDM_channel_from_file::sub_channel(uint32_t from_node_ix,
00611 uint32_t to_node_ix, 
00612            uint32_t from_antenna_ix, uint32_t to_antenna_ix 
00613                  , double freq_tx, double freq_rx,
00614                                  double time, double gain_tx, double gain_rx, 
00615 std::complex<short int> const* signal_in, std::complex<short int>* signal_out,
00616 uint32_t number_of_samples) {
00617 
00618   cvec s_in, s_out;
00619   
00620   if (time>t_old) {
00621     d_frame_ix++;
00622     std::stringstream temp_ss;
00623     temp_ss << d_frame_ix;  
00624     load_file(d_filename+"_frame_ix="+temp_ss.str()+".dat");
00625     t_old=time;
00626   };
00627 
00628 
00629   // Set length of ITPP vectors
00630   s_in.set_length(number_of_samples);
00631   s_out.set_length(number_of_samples);
00632 
00633   // Convert input to cvec
00634   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00635     s_in[i1]=signal_in[i1];
00636   };
00637   s_in/=d_signal_scaling;
00638 
00639   // Convert receiver buffer to cvec
00640   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00641     s_out[i1]=signal_out[i1];
00642   };
00643   
00644   // Do the channel model
00645   int sample_ix=d_tx_start_sample;
00646   cvec w(d_Nfft), W(d_Nfft);
00647   cvec Hc(d_Nfft);
00648   cvec st(d_Nfft), St(d_Nfft);
00649   bool cond=true;
00650 
00651   Hc.zeros();
00652 
00653   while (cond) {
00654 
00655     for (int i1=0;i1<d_ix_all.length();i1++){
00656       Hc(d_ix_all(i1))
00657         =H[from_node_ix][to_node_ix][from_antenna_ix](to_antenna_ix,i1);
00658     };
00659     Hc=std::polar(1.0,rand_cpe(from_antenna_ix,from_node_ix)*0.017453)*Hc;
00660 
00661     w=s_in.mid(sample_ix,d_Nfft);
00662     W=fft(w);    
00663     St=elem_mult(Hc,W);
00664     st=ifft(St);
00665     double c=sum_sqr(abs(st))/((double) d_Nfft);
00666     
00667     c=c*(((double) (d_Nfft))/((double) (d_ix_all.length())))*
00668       (((double) (d_Nfft))/((double) (d_ix_all.length())));
00669     c=d_EVM*sqrt(c);
00670     st=st+c*randn_c(d_Nfft);
00671     
00672     
00673     for (int i1=0;i1<d_Nfft;i1++) {
00674       s_out[sample_ix+d_rx_start_sample-d_tx_start_sample+i1]+=st(i1);
00675     };
00676     sample_ix+=d_Nfft+d_Nc;
00677 
00678     cond=sample_ix<((int) number_of_samples-d_Nfft);
00679     cond=cond && (sample_ix+d_rx_start_sample-d_tx_start_sample+d_Nfft+d_Nc <
00680                   (int) number_of_samples);
00681 
00682       counter++;
00683 
00684   };
00685 
00686 
00687   // Convert output to  std::complex<short int>
00688   for (int i1=0;i1<(int) number_of_samples;i1++) {
00689     signal_out[i1]=s_out[i1];
00690   };   
00691 };
00692 
00693 
00694 void OFDM_channel_from_file::add_noise(double gain_rx, 
00695         std::complex<short int>* signal, 
00696                                  uint32_t number_of_samples) {
00697 
00698   itpp::cvec s, n, n_evm;
00699 
00700   // Save the old seed and create a random
00701   ivec seed_state;
00702   RNG_get_state(seed_state);
00703   RNG_randomize();
00704 
00705 
00706   // Set length of ITPP vectors
00707   s.set_length(number_of_samples);
00708 
00709   // Convert input to cvec
00710   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00711     s[i1]=signal[i1];
00712   };
00713 
00714   // Calculate power for receive EVM generation
00715   double power=0.0;
00716   double power_local=0;
00717   int sample_ix=d_rx_start_sample;
00718   int no_of_symbols=0;
00719   bool cond=sample_ix<((int) number_of_samples-d_Nfft);
00720   while (cond) {
00721     power_local=0.0;
00722     for (int i1=0;i1<d_Nfft;i1++) {
00723       power_local+=abs(s(sample_ix))*abs(s(sample_ix));
00724     };
00725     power_local=power_local/((double) d_Nfft);
00726     if (sqrt(power_local)>10) {
00727       power+=power_local;
00728       no_of_symbols++;
00729     };
00730     sample_ix+=d_Nfft+d_Nc;
00731     cond=sample_ix<((int) number_of_samples-d_Nfft);
00732   };
00733 
00734   power*=(((double) (d_Nfft))/((double) (d_ix_all.length())))*
00735       (((double) (d_Nfft))/((double) (d_ix_all.length())));
00736   power=power/((double) no_of_symbols);
00737 
00738   // Generate noise
00739   n=itpp::randn_c(number_of_samples);
00740   n=scaling_noise*n;
00741 
00742   // Generate RX EVM
00743   n_evm=itpp::randn_c(number_of_samples);
00744   n_evm=d_EVM_RX*sqrt(power)*n_evm;
00745 
00746 
00747   // Add noise and EVM
00748   //s=s+n+n_evm;
00749 
00750   // Convert output to  std::complex<short int>
00751   for (uint32_t i1=0;i1<number_of_samples;i1++) {
00752      signal[i1]=s[i1];
00753   };
00754 
00755   // Reset the seed
00756   RNG_set_state(seed_state);
00757 
00758   
00759 
00760 }
 All Classes Functions Variables