four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
modem/modem_OFDM1.hpp
00001 /*
00002  * Copyright 2011-2013, Per Zetterberg
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 /* This code should implement, more or less, the same functions as 
00019  * 
00020  * mod_OFDM1.m and demod_OFDM1.m
00021  *
00022  *
00023  */
00024 
00025 #include <itpp/itcomm.h>
00026 #include <complex>
00027 
00028  
00029 using namespace std;
00030 using namespace itpp;
00031 
00032 #ifndef MODEM_OFDM1_H
00033 #define MODEM_OFDM1_H
00034 
00042 class OFDM1 {
00043 
00044 public:
00045 
00046   static const uint32_t rightmost_carrier=19;
00047   static const uint32_t leftmost_carrier=61;
00048   static const uint32_t Nfft=80;
00049   static const uint32_t pilot_carrier1=10;
00050   static const uint32_t pilot_carrier2=71;
00051   static const uint32_t Nfft_sync=65536; // Frequency offsets with 25e6/Nfft_sync spacing.
00052   static const uint32_t gap=3;
00053   
00054 
00055   ivec known_symbol_pos;
00056   ivec interferers_known_pos;
00057   uint32_t Ns;//, nof_symbols_storage;
00058   complex<double> pilot_symbol;
00059   //uint32_t storage_ix;
00060   ivec ix, ix_all, ix_sub;
00061   cvec debug1;
00062   cvec debug2;
00063   uint32_t length_ix, length_ix_all;
00064   int pilot_carrier1_sub, pilot_carrier2_sub;
00065   int rightmost_carrier_sub, leftmost_carrier_sub;
00066   //cvec ConstellationStorage; //(length_ix*nof_symbols_storage);
00067   cvec train;
00068   cvec h;
00069   cvec pulse_shape;
00070   int pulse_shape_delay;
00071   bool do_use_pilot_carriers, do_prepend_training;
00072   uint32_t Np;
00073   ivec d_reorder;
00074   double pilot_power_factor;
00075   cmat he; // Channel estimate of desired signal stream
00076   cmat hi[10]; // Channel estimate of at most 10 interfering signal streams
00077   cmat x[100]; // Max 100 OFDM symbols
00078   cmat x_c;
00079   bool estimate_SINR; // If you want the receiver to estimate it's own SINR.
00080   double SINR; // Here's the result.
00081   int noise_estimation_start_ix, noise_estimation_stop_ix; // Defines where
00082                                    // in the buffer samples can be taken for
00083                                    // additive noise estimation.
00084 
00085   //OFDM1(bool use_pilot_carriers, bool prepend_training,uint32_t prefix_length);
00086 
00091   OFDM1(void);
00092 
00093 
00095   uint32_t Nfftr(void){return Nfft;};
00096 
00098   uint32_t number_of_modulation_symbols(void);
00099 
00101   uint32_t waveform_length(void);
00102 
00104   uint32_t prefix_length(void) { return Np; };
00105   
00108   ivec start_of_known_symbol(void);
00109   
00118   void init_multi_antenna(uint32_t no_ant, int32_t buffer_size, ivec &interferer_pos);
00119 
00121   void pilot_pattern(cvec &burst, cvec precoder);
00122 
00130   void insert_pilot(cvec &waveform, uint32_t symbol_number, uint32_t offset,
00131 cvec precoder);
00132  
00133   
00146 void modulate(cvec &waveform,const cvec &symbols_in,  
00147                const uint32_t offset,double &rms_power,const cvec &precoder);
00148 
00157   void estimate_channel(cvec waveform,double  &noise_variance_normalized,cvec &h, uint32_t start_sample);  
00158 
00168   void estimate_channel(cvec waveform,double  &noise_variance_normalized,
00169                       cvec &h, uint32_t start_sample, double &noise_variance);
00170 
00181   void demodulate(const cvec &waveform,cvec &symbols_out, uint32_t start_sample,
00182            const cvec &h, double &rms_signal);
00183 
00184 
00186   void demodulate_multi_antenna(const cmat &waveform,vec &soft_bit, uint32_t start_sample, int modulation_order);
00187 
00188 
00200   void extract_multi_antenna(const cmat &waveform,uint32_t start_sample);
00201  
00202 
00214   void extract_multi_antenna(const cmat &waveform,
00215                              uint32_t start_sample, cvec &symbols_out); 
00216 
00217   /* \brief Synchronize against synchronization sequence (i.e. the
00218 sequence which is pre-pended if prepend_training=true when calling init),
00219 and simultaneosly search for frequency offset. The function is only
00220 implemented based for using a single antenna.
00221     \param waveform Received samples.
00222     \param start_pos Estimated start position.
00223     \param f_offset Estimated frequency offset.
00224 */
00225   void synchronize(cvec &waveform, uint32_t &start_pos,double &f_offset);
00226 
00227   /* \brief Synchronize against synchronization sequence (i.e. the
00228 sequence which is pre-pended if prepend_training=true when calling init),
00229 and simultaneosly search for frequency offset. The function is only
00230 implemented based for using a single antenna.
00231     \param waveform Received samples.
00232     \param start_pos Estimated start position.
00233 */
00234   void synchronize(cvec &waveform, uint32_t &start_pos);
00235 
00246   void init(bool use_pilot_carriers, bool prepend_training,uint32_t prefix_length,uint32_t Ns, ivec known_pos, ivec re_order);
00247 
00256   void interleave_symbols(cvec &symbol, int index);
00257 
00266   void de_interleave_symbols(cvec &symbol, int index);
00267 
00269   void pz_init_fft(void){
00270     double a;
00271     Wfft.set_size(Nfft,Nfft);
00272     Wifft.set_size(Nfft,Nfft);
00273 
00274     for (uint32_t i1=0;i1<Nfft;i1++) {
00275       for (uint32_t i2=0;i2<Nfft;i2++) {
00276         a=-2*pi;
00277         a=a*i1;
00278         a=a*i2;
00279         a=a/Nfft;
00280         Wfft(i1,i2)=polar(1.0,a);
00281         a=2*pi;
00282         a=a*i2;
00283         a=a*i1;
00284         a=a/Nfft;
00285         Wifft(i1,i2)=polar((1.0/Nfft),a);
00286       };
00287     };  
00288 
00289   };
00290 
00292   void pz_fft(const cvec &in,cvec &out) { out=Wfft*in; };
00293 
00295   void pz_ifft(const cvec &in,cvec &out) { out=Wifft*in; };
00296 
00297   cmat Wfft;
00298   cmat Wifft;
00299 
00300   imat symbol_interleave_matrix;
00301   imat symbol_de_interleave_matrix;
00302   
00303 
00304 };
00305 
00306 #endif
00307 
 All Classes Functions Variables