![]() |
four_multi
Multi-Antenna,Multi-Node,Multi-Band,Multi-Cell
|
00001 /* 00002 * Copyright 2012-2013, Per Zetterberg, KTH Royal Institute of Technology 00003 * 00004 * This program is free software: you can redistribut 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 implemen, 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 <itpp/stat/misc_stat.h> 00027 #include <math.h> 00028 #include "modem_OFDM1.hpp" 00029 #include <itpp/itbase.h> 00030 #include <complex> 00031 #include <itpp/base/sort.h> 00032 00033 00034 using namespace itpp; 00035 using namespace std; 00036 00037 OFDM1::OFDM1(void){ 00038 pilot_power_factor=1; 00039 estimate_SINR=false; 00040 pulse_shape="0.0546,-0.0898,-0.0587,0.3134,0.5612,0.3133,-0.0587,-0.0898,0.0546"; 00041 pulse_shape_delay=4; 00042 }; 00043 00044 00045 uint32_t OFDM1::number_of_modulation_symbols(void){ 00046 return ((Ns-known_symbol_pos.length())*length_ix); 00047 }; 00048 00049 uint32_t OFDM1::waveform_length(void){ 00050 return (max(d_reorder)*Ns*(Nfft+Np)); 00051 }; 00052 00053 00054 void OFDM1::init(bool use_pilot_carriers, bool prepend_training,uint32_t prefix_length,uint32_t number_of_symbols, ivec known_symbol_postion_index, ivec reorder){ 00055 00056 pz_init_fft(); 00057 Ns=number_of_symbols; 00058 known_symbol_pos=known_symbol_postion_index; 00059 d_reorder=reorder; 00060 00061 do_use_pilot_carriers=use_pilot_carriers; 00062 do_prepend_training=prepend_training; 00063 00064 Np=prefix_length; 00065 00066 if (do_use_pilot_carriers) 00067 length_ix=36; 00068 else 00069 length_ix=38; 00070 00071 length_ix_all=38; 00072 00073 pilot_symbol=1.0+1.0i; 00074 h.set_size(Nfft); 00075 00076 00077 string temp_str; 00078 temp_str="1,1,-1,1,1,1,1,-1,1,1,1,-1,1,1,1,-1,-1,-1,1,1,1,1, "; 00079 temp_str+="-1,-1,-1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,1,1,-1,-1,-1, "; 00080 temp_str+="-1,1,1,1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,-1,-1,-1,1,-1,-1,1, "; 00081 temp_str+="1,1,1,-1,1,-1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1, "; 00082 temp_str+="-1,1,1,-1,-1,1,-1,1,-1,1,1,1,1,1,-1,1,1,1,-1,1,-1,-1,1,-1,-1, "; 00083 temp_str+="1,1,-1,1,1,1,1,1,1,-1,1,-1,-1,-1,1,-1,-1,1,-1,1 "; 00084 train=temp_str.c_str(); 00085 ix.set_size(length_ix); 00086 00087 00088 00089 { uint32_t counter=0; 00090 for (uint32_t i1=1;i1<pilot_carrier1;i1++) { 00091 ix(counter++)=i1; 00092 }; 00093 00094 for (uint32_t i1=pilot_carrier1+1;i1<=rightmost_carrier;i1++) { 00095 ix(counter++)=i1; 00096 }; 00097 rightmost_carrier_sub=counter-1; 00098 leftmost_carrier_sub=counter; 00099 00100 for (uint32_t i1=leftmost_carrier;i1<pilot_carrier2;i1++) { 00101 ix(counter++)=i1; 00102 }; 00103 00104 for (uint32_t i1=pilot_carrier2+1;i1<Nfft;i1++){ 00105 ix(counter++)=i1; 00106 }; 00107 }; 00108 00109 ix_all.set_size(length_ix_all); 00110 {uint32_t counter=0; 00111 00112 for (uint32_t i1=1;i1<=rightmost_carrier;i1++) { 00113 ix_all(counter++)=i1; 00114 }; 00115 for (uint32_t i1=leftmost_carrier;i1<Nfft;i1++) { 00116 ix_all(counter++)=i1; 00117 }; 00118 00119 }; 00120 00121 00122 ix_sub.set_size(length_ix); 00123 {int counter=0; 00124 for (uint32_t i1=0;i1<(length_ix+2);i1++) { 00125 for (uint32_t i2=0;i2<length_ix;i2++) { 00126 if (ix_all(i1)==ix(i2)) { 00127 ix_sub(counter)=i1; 00128 counter++; 00129 }; 00130 }; 00131 }; 00132 }; 00133 00134 for (uint32_t i1=0;i1<length_ix+2;i1++) { 00135 if (ix_all(i1)==(int32_t) pilot_carrier1) { 00136 pilot_carrier1_sub=i1; 00137 }; 00138 00139 if (ix_all(i1)==(int32_t) pilot_carrier2) { 00140 pilot_carrier2_sub=i1; 00141 }; 00142 }; 00143 00144 if (!do_use_pilot_carriers) { 00145 ix=ix_all; 00146 for (uint32_t i1=0;i1<length_ix;i1++) 00147 ix_sub(i1)=i1; 00148 }; 00149 00150 int no_interleavers=8; 00151 symbol_interleave_matrix.set_size(no_interleavers,length_ix); 00152 symbol_de_interleave_matrix.set_size(no_interleavers,length_ix); 00153 RNG_reset(101); 00154 ivec temp1(length_ix), temp2(length_ix); 00155 Sort<double> my_sort_f; 00156 Sort<int> my_sort_i; 00157 00158 for (int i1=0;i1<no_interleavers;i1++) { 00159 temp1=my_sort_f.sort_index(0,(int) (length_ix-1),randu(length_ix)); 00160 temp2=my_sort_i.sort_index(0,(int) (length_ix-1),temp1); 00161 00162 symbol_interleave_matrix.set_row(i1,temp1); 00163 symbol_de_interleave_matrix.set_row(i1,temp2); 00164 }; 00165 00166 00167 00168 00169 } ; 00170 00171 void OFDM1::pilot_pattern(cvec &burst, cvec precoder) { 00172 00173 00174 burst(0)=0.0+0.0i; burst(1)=-1.0-1.0i; burst(2)=-1.0-1.0i; 00175 burst(3)=1.0+1.0i; burst(4)=-1.0-1.0i; 00176 burst(5)=1.0+1.0i; burst(6)=-1.0-1.0i; burst(7)=1.0+1.0i; 00177 burst(8)=1.0+1.0i; burst(9)=-1.0-1.0i; 00178 burst(10)=-1.0-1.0i; burst(11)=-1.0+1.0i; 00179 burst(12)=-1.0+1.0i; burst(13)=1.0+1.0i; 00180 burst(14)=-1.0+1.0i; burst(15)=-1.0+1.0i; 00181 burst(16)=-1.0+1.0i; burst(17)=1.0+1.0i; 00182 burst(18)=1.0+1.0i; burst(19)=1.0+1.0i; 00183 burst(20)=0.0+0.0i; burst(21)=0.0+0.0i; 00184 burst(22)=0.0+0.0i; burst(23)=0.0+0.0i; 00185 burst(24)=0.0+0.0i; burst(25)=0.0+0.0i; 00186 burst(26)=0.0+0.0i; burst(27)=0.0+0.0i; 00187 burst(28)=0.0+0.0i; burst(29)=0.0+0.0i; 00188 burst(30)=0.0+0.0i; burst(31)=0.0+0.0i; 00189 burst(32)=0.0+0.0i; burst(33)=0.0+0.0i; 00190 burst(34)=0.0+0.0i; burst(35)=0.0+0.0i; 00191 burst(36)=0.0+0.0i; burst(37)=0.0+0.0i; 00192 burst(38)=0.0+0.0i; burst(39)=0.0+0.0i; 00193 burst(40)=0.0+0.0i; burst(41)=0.0+0.0i; 00194 burst(42)=0.0+0.0i; burst(43)=0.0+0.0i; 00195 burst(44)=0.0+0.0i; 00196 burst(45)=0.0+0.0i; burst(46)=0.0+0.0i; 00197 burst(47)=0.0+0.0i; burst(48)=0.0+0.0i; 00198 burst(49)=0.0+0.0i; burst(50)=0.0+0.0i; 00199 burst(51)=0.0+0.0i; burst(52)=0.0+0.0i; 00200 burst(53)=0.0+0.0i; burst(54)=0.0+0.0i; 00201 burst(55)=0.0+0.0i; burst(56)=0.0+0.0i; 00202 burst(57)=0.0+0.0i; burst(58)=0.0+0.0i; 00203 burst(59)=0.0+0.0i; burst(60)=0.0+0.0i; 00204 burst(61)=-1.0+1.0i; burst(62)=1.0+1.0i; 00205 burst(63)=-1.0-1.0i; burst(64)=-1.0+1.0i; 00206 burst(65)=1.0+1.0i; burst(66)=-1.0-1.0i; 00207 burst(67)=-1.0-1.0i; burst(68)=1.0+1.0i; 00208 burst(69)=-1.0+1.0i; burst(70)=-1.0-1.0i; burst(71)=-1.0+1.0i; 00209 burst(72)=-1.0-1.0i; burst(73)=-1.0+1.0i; burst(74)=-1.0+1.0i; 00210 burst(75)=-1.0-1.0i; burst(76)=1.0+1.0i; 00211 burst(77)=-1.0-1.0i; burst(78)=-1.0+1.0i; 00212 burst(79)=1.0+1.0i; 00213 00214 for (uint32_t i1=0;i1<Nfft;i1++) { 00215 burst(i1)=burst(i1)*pilot_power_factor/sqrt(2); 00216 }; 00217 00218 00219 for (uint32_t i1=0;i1<length_ix_all;i1++) { 00220 burst(ix_all(i1))=burst(ix_all(i1))*precoder(i1); 00221 }; 00222 00223 00224 }; 00225 00226 00227 ivec OFDM1::start_of_known_symbol(void){ 00228 ivec temp; 00229 temp.set_length(known_symbol_pos.length()); 00230 for (int i1=0;i1<known_symbol_pos.length();i1++) { 00231 temp(i1)=d_reorder.get(known_symbol_pos(i1))*(Nfft+Np); 00232 }; 00233 return temp; 00234 }; 00235 00236 00237 00238 void OFDM1::modulate(cvec &waveform,const cvec &symbols_in, 00239 const uint32_t offset, 00240 double &rms_power,const cvec &precoder) 00241 00242 { 00243 00244 cvec symbol(Nfft), symbol_temp(Nfft); 00245 cvec waveform_temp(Nfft); 00246 double power=0,temp; 00247 bool the_symbol_is_known; 00248 int i4; // Counter from symbols_in 00249 00250 i4=0; 00251 symbol.zeros(); 00252 00253 for (int i1=0;i1<(int) Ns;i1++) { 00254 00255 the_symbol_is_known=false; 00256 for (int i2=0;i2<known_symbol_pos.length();i2++) { 00257 if (i1==known_symbol_pos(i2)) 00258 the_symbol_is_known=true; 00259 }; 00260 00261 00262 00263 if (the_symbol_is_known) { 00264 00265 pilot_pattern(symbol,precoder); 00266 00267 00268 } else { 00269 00270 for (uint32_t i3=0;i3<length_ix;i3++) { 00271 symbol(ix(i3))=symbols_in(i4)*precoder(ix_sub(i3)); 00272 i4++; 00273 }; 00274 if (do_use_pilot_carriers) { 00275 symbol[pilot_carrier1]=(1.0+1.0i)/sqrt(2); 00276 symbol[pilot_carrier2]=(1.0+1.0i)/sqrt(2); 00277 symbol[pilot_carrier1]*=precoder(pilot_carrier1_sub); 00278 symbol[pilot_carrier2]*=precoder(pilot_carrier2_sub); 00279 }; 00280 }; 00281 00282 00283 //waveform_temp=ifft(symbol,Nfft); 00284 pz_ifft(symbol,waveform_temp); 00285 waveform_temp=concat(waveform_temp.mid(Nfft-Np,Np),waveform_temp); 00286 waveform_temp=filter(pulse_shape,1,waveform_temp); 00287 00288 if (rms_power!=-10) { 00289 temp=norm(waveform_temp.mid(Np,Nfft)); 00290 power=power+temp*temp; 00291 temp=norm(waveform_temp); 00292 power=power+temp*temp; 00293 }; 00294 00295 int replace_pos=d_reorder(i1)*(Nfft+Np)+offset-pulse_shape_delay; 00296 00297 if (replace_pos<0) { 00298 std::cout << "writing outside of waveform in OFDM1::modulate \n"; 00299 exit(1); 00300 }; 00301 00302 for (int i2=0;i2<waveform_temp.size();i2++) { 00303 waveform(i2+replace_pos)+=waveform_temp(i2); 00304 }; 00305 00306 00307 00308 }; 00309 if (rms_power!=-10) { 00310 power=power/(Ns*Nfft); 00311 rms_power=sqrt(power); 00312 }; 00313 00314 00315 }; 00316 00317 00318 00319 00320 void OFDM1::insert_pilot(cvec &waveform, uint32_t symbol_position, uint32_t offset, 00321 cvec precoder) { 00322 cvec symbol(Nfft); 00323 cvec waveform_temp(Nfft); 00324 symbol.zeros(); 00325 pilot_pattern(symbol,precoder); 00326 //waveform_temp=ifft(symbol,Nfft); 00327 pz_ifft(symbol,waveform_temp); 00328 00329 waveform.replace_mid(symbol_position*(Nfft+Np)+Np+offset,waveform_temp); 00330 waveform.replace_mid(symbol_position*(Nfft+Np)+offset,waveform_temp.mid(Nfft-Np,Np)); 00331 }; 00332 00333 00334 void OFDM1::estimate_channel(cvec waveform,double &noise_variance_normalized, 00335 cvec &h, uint32_t start_sample) { 00336 double noise_variance; 00337 estimate_channel(waveform,noise_variance_normalized,h,start_sample,noise_variance); 00338 00339 }; 00340 00341 00342 00343 void OFDM1::estimate_channel(cvec waveform,double &noise_variance_normalized, 00344 cvec &h, uint32_t start_sample, double &noise_variance) { 00345 00346 cvec pilot(Nfft); 00347 int i1,counter; 00348 complex <double> hhat, actual_meas, ideal_meas, error; 00349 double error_div_h; 00350 cvec signal(Nfft); 00351 cvec h_rotated(Nfft); 00352 complex<double> rotation; 00353 00354 00355 00356 //signal=fft(waveform.mid(0,Nfft)); 00357 pz_fft(waveform.mid(start_sample,Nfft),signal); 00358 pilot.set_length(Nfft); 00359 pilot_pattern(pilot,ones_c(length_ix_all)); 00360 h=signal(ix_all); 00361 h/=pilot(ix_all); 00362 00363 00364 00365 noise_variance_normalized=0; 00366 noise_variance=0; 00367 counter=0; 00368 00369 for (i1=1;i1<ix_all.length()-1;i1++) { 00370 00371 if (((ix_all(i1)-ix_all(i1-1))==1) && ((ix_all(i1+1)-ix_all(i1))==1)) { 00372 00373 hhat=0.5*abs(h(i1-1))+0.5*abs(h(i1+1)); 00374 complex<double> t; 00375 t=h(i1+1)/h(i1-1); 00376 double a=arg(h(i1-1))+0.5*arg(t); 00377 hhat=polar(abs(hhat),a); 00378 ideal_meas=hhat*pilot(ix_all(i1)); 00379 00380 actual_meas=signal(ix_all(i1)); 00381 error=ideal_meas-actual_meas; 00382 00383 noise_variance+=abs(error)*abs(error); 00384 error_div_h=abs(error)/abs(h(i1)); 00385 noise_variance_normalized+=error_div_h*error_div_h; 00386 counter++; 00387 } 00388 }; 00389 noise_variance_normalized/=counter; 00390 noise_variance/=counter; 00391 00392 00393 00394 }; 00395 00396 00397 00398 void OFDM1::init_multi_antenna(uint32_t no_ant, int32_t buffer_size, ivec &interferers_known_pos_in) { 00399 00400 for (uint32_t i1=0;i1<Ns;i1++) { 00401 x[i1].set_size(no_ant,length_ix_all); 00402 }; 00403 he.set_size(no_ant,length_ix_all); 00404 interferers_known_pos=interferers_known_pos_in; 00405 for (int i1=0;i1<interferers_known_pos.length();i1++) { 00406 hi[i1].set_size(no_ant,length_ix_all); 00407 }; 00408 00409 int num_payload_symbols=0; 00410 bool the_symbol_is_known; 00411 for (int i1=0;i1<(int) Ns;i1++) { 00412 the_symbol_is_known=false; 00413 for (int i2=0;i2<known_symbol_pos.length();i2++) { 00414 if (i1==known_symbol_pos(i2)) 00415 the_symbol_is_known=true; 00416 }; 00417 00418 if (!(the_symbol_is_known)) { 00419 num_payload_symbols++; 00420 }; 00421 }; 00422 00423 x_c.set_size(length_ix_all,num_payload_symbols); 00424 00425 00426 } 00427 00428 00429 void OFDM1::demodulate_multi_antenna(const cmat &waveform,vec &soft_bit, uint32_t start_sample, int modulation_order){ 00430 00431 cvec waveform_temp(Nfft); 00432 double noise_variance, noise_variance_norm; 00433 vec noise_variance_vec; // Noise variance estmimated during pilot. 00434 vec noise_variance_SINR; // Noise variance estmimated when there is 00435 // no signal. Only for benchmarking 00436 vec soft_temp; 00437 cvec symbolsc(Nfft); 00438 bool the_symbol_is_known; 00439 int32_t num_payload_symbols; 00440 double D=0.0, DI=0.0; 00441 00442 noise_variance_vec.set_length(waveform.rows()); 00443 // Estimate noise variance for analysis purposes 00444 00445 if (estimate_SINR) { 00446 noise_variance_SINR.set_length(waveform.rows()); 00447 int Nsymb; 00448 int start_ix=noise_estimation_start_ix; 00449 int stop_ix; 00450 00451 for (int i2=0;i2<waveform.rows();i2++) { 00452 noise_variance_SINR(i2)=0; 00453 start_ix=noise_estimation_start_ix; 00454 stop_ix=start_ix+Nfft; 00455 Nsymb=0; 00456 while (stop_ix<noise_estimation_stop_ix) { 00457 waveform_temp=(waveform.get_row(i2)).mid(start_ix,Nfft); 00458 pz_fft(waveform_temp,symbolsc); 00459 noise_variance_SINR(i2)+=sum(sqr(symbolsc(ix_all)))/length_ix_all; 00460 start_ix=stop_ix+1; 00461 stop_ix=start_ix+Nfft; 00462 Nsymb++; 00463 }; 00464 noise_variance_SINR(i2)=noise_variance_SINR(i2)/Nsymb; 00465 }; 00466 }; 00467 00468 // Do FFT on all signals except pilot 00469 int i10=0; 00470 for (int i1=0;i1<(int) Ns;i1++) { 00471 the_symbol_is_known=false; 00472 for (int i2=0;i2<known_symbol_pos.length();i2++) { 00473 if (i1==known_symbol_pos(i2)) 00474 the_symbol_is_known=true; 00475 }; 00476 00477 if (!(the_symbol_is_known)) { 00478 for (int i2=0;i2<waveform.rows();i2++) { 00479 waveform_temp=(waveform.get_row(i2)).mid((Nfft+Np)*d_reorder(i1)+start_sample,Nfft); 00480 //symbolsc=fft(waveform_temp); 00481 pz_fft(waveform_temp,symbolsc); 00482 x[i10].set_row(i2,symbolsc(ix_all)); 00483 }; 00484 i10++; 00485 }; 00486 }; 00487 num_payload_symbols=i10; 00488 00489 if (modulation_order==0) return; 00490 00491 // Estimate the vector channel of desired signal and interferers 00492 for (int i2=0;i2<he.rows();i2++) { 00493 double dummy; 00494 00495 int s=start_of_known_symbol()(0)+start_sample; 00496 waveform_temp=(waveform.get_row(i2)).mid(s,Nfft); 00497 estimate_channel(waveform_temp,noise_variance_norm, 00498 h,0,noise_variance); 00499 00500 noise_variance_vec(i2)=noise_variance; 00501 he.set_row(i2,h); 00502 for (int i1=0;i1<interferers_known_pos.length();i1++) { 00503 s=start_sample+interferers_known_pos(i1)*(Nfft+Np); 00504 waveform_temp=(waveform.get_row(i2)).mid(s,Nfft); 00505 estimate_channel(waveform_temp,dummy,h,0); 00506 hi[i1].set_row(i2,h); 00507 }; 00508 }; 00509 00510 noise_variance=mean(noise_variance_vec); 00511 00512 if (modulation_order==1) return; 00513 00514 00515 cmat Rs; // Structured covariance matrix 00516 cmat Ru; // Un-structured covariance matrix 00517 cmat temp; 00518 cvec temp1; 00519 complex<double> hc; 00520 cvec w(waveform.rows()); 00521 00522 00523 Rs.set_size(waveform.rows(),waveform.rows()); 00524 Ru.set_size(waveform.rows(),waveform.rows()); 00525 00526 temp.set_size(waveform.rows(),waveform.rows()); 00527 temp1.set_length(waveform.rows()); 00528 00529 for (uint32_t i2=0;i2<length_ix_all;i2++) { 00530 00531 Ru.zeros(); 00532 for (int i1=0;i1<num_payload_symbols;i1++) { 00533 temp1=(x[i1]).get_col(i2); 00534 Ru+=outer_product(temp1,temp1,true); 00535 }; 00536 Rs=outer_product(he.get_col(i2),he.get_col(i2),true); 00537 for (int i1=0;i1<interferers_known_pos.length();i1++) { 00538 Rs=Rs+outer_product(hi[i1].get_col(i2),hi[i1].get_col(i2),true); 00539 }; 00540 Rs=Rs+diag(noise_variance_vec); 00541 w=inv(Rs)*he.get_col(i2); 00542 w=w/norm(w,2); 00543 00544 if (estimate_SINR) { 00545 double d; 00546 DI+=abs(elem_mult_sum(conj(w),(Rs+ 00547 diag(noise_variance_SINR-noise_variance_vec))*w)); 00548 d=abs(elem_mult_sum(conj(w),he.get_col(i2))); 00549 D+=d*d; 00550 }; 00551 00552 00553 h(i2)=elem_mult_sum(he.get_col(i2),conj(w)); 00554 for (int i1=0;i1<num_payload_symbols;i1++) { 00555 x_c(i2,i1)=elem_mult_sum(x[i1].get_col(i2),conj(w)); 00556 }; 00557 00558 }; 00559 00560 if (estimate_SINR) { 00561 SINR=D/(DI-D); 00562 }; 00563 00564 if (modulation_order==2) return; 00565 00566 #if 0 00567 cvec symbol; 00568 symbol.set_length(length_ix_all); 00569 soft_temp.set_length(length_ix); 00570 int bits_per_symbol=log2(modulation_order); 00571 00572 // Re-estimate noise variance 00573 double noise_variance_temp; 00574 noise_variance=0; 00575 for (int i1=0;i1<num_payload_symbols;i1++) { 00576 symbol=x_c.get_col(i1); 00577 noise_variance_temp=0; 00578 soft_output(symbol,noise_variance_temp,modulation_order,soft_temp); 00579 noise_variance+=noise_variance_temp; 00580 }; 00581 noise_variance/=num_payload_symbols; 00582 00583 00584 // Soft-value extraction 00585 for (int i1=0;i1<num_payload_symbols;i1++) { 00586 symbol=x_c.get_col(i1); 00587 soft_output(symbol,noise_variance,modulation_order,soft__temp); 00588 soft_bit.replace_mid(i1*length_ix*bits_per_symbol,soft_temp); 00589 }; 00590 #endif 00591 }; 00592 00593 void OFDM1::extract_multi_antenna(const cmat &waveform, 00594 uint32_t start_sample){ 00595 00596 // When calling this function the following members will be set 00597 // x_c : A matrix which contains the combined signal (#subcarrier,#symbol) 00598 // h : Channel estimate including combiner #subcarriers 00599 // x[#symbols]: The raw complex samples. Each matrix (#subcarrier,#symbol). 00600 // he: Channel estimate for the desired signal (#antenna,#subcarrier) 00601 // hi[#interferers]: Channel estimate of interfering signals. 00602 00603 vec dummy; 00604 00605 demodulate_multi_antenna(waveform,dummy,start_sample,2); 00606 }; 00607 00608 00609 void OFDM1::extract_multi_antenna(const cmat &waveform, 00610 uint32_t start_sample, cvec &symbols_out){ 00611 00612 // As the short version but also including equalization and estimation of the noise 00613 // in the equalized samples 00614 00615 vec dummy; 00616 cvec signal(length_ix_all); 00617 std::complex<double> cpec; 00618 00619 demodulate_multi_antenna(waveform,dummy,start_sample,2); 00620 00621 00622 uint32_t i3=0; 00623 //std::cout << "h=" << h << "; \n"; 00624 //std::cout << "x_c=" << x_c << "; \n"; 00625 00626 for (int i1=0;i1<x_c.cols();i1++) { 00627 00628 elem_div_out( x_c.get_col(i1),h,signal); 00629 00630 if (do_use_pilot_carriers) { 00631 // Common phase error correction (CPEC) 00632 //cpec=pilot_symbol/(signal(pilot_carrier1_sub)/h(pilot_carrier1_sub)+ 00633 // signal(pilot_carrier2_sub)/h(pilot_carrier2_sub)); 00634 00635 cpec=pilot_symbol/signal(pilot_carrier1_sub)+ 00636 pilot_symbol/signal(pilot_carrier2_sub); 00637 cpec=cpec/abs(cpec); 00638 signal=signal*cpec; 00639 00640 }; 00641 00642 for (uint32_t i2=0;i2<length_ix;i2++) { 00643 symbols_out(i3)=signal(ix_sub(i2)); 00644 i3=i3+1; 00645 }; 00646 }; 00647 00648 00649 }; 00650 00651 #if 0 00652 void OFDM1::extract_multi_antenna(const cmat &waveform, 00653 uint32_t start_sample, cvec &symbols_out){ 00654 00655 // As the short version but also including equalization and estimation of the noise 00656 // in the equalized samples 00657 00658 //QAM modulation; 00659 vec dummy; 00660 //cvec symbol(1); 00661 //cvec closest_constellation_point(1); 00662 00663 //modulation.set_M(modulation_order); 00664 demodulate_multi_antenna(waveform,dummy,start_sample,2); 00665 00666 00667 uint32_t i3=0; 00668 cvec temp(length_ix); 00669 00670 for (int i1=0;i1<x_c.cols();i1++) { 00671 elem_div_out( x_c.get_col(i1),h(ix_sub),temp); 00672 for (uint32_t i2=0;i2<length_ix;i2++) { 00673 symbols_out(i3)=temp(i2); 00674 i3=i3+1; 00675 }; 00676 }; 00677 00678 00679 }; 00680 #endif 00681 00682 00683 00684 void OFDM1::demodulate(const cvec &waveform,cvec &symbols_out, uint32_t start_sample, const cvec &h, double &rms_signal) 00685 { 00686 double power,temp; 00687 cvec symbolsc(Nfft); 00688 vec soft_temp; 00689 bool the_symbol_is_known; 00690 cvec signal(Nfft), demodulator_input; 00691 int i4; // Counter in symbols_out 00692 std::complex<double> cpec; 00693 int s; 00694 00695 demodulator_input.set_length(length_ix); 00696 00697 i4=0; 00698 power=0.0; 00699 cpec=1.0; 00700 00701 for (int i1=0;i1<(int) Ns;i1++) { 00702 00703 00704 the_symbol_is_known=false; 00705 for (int i2=0;i2<known_symbol_pos.length();i2++) { 00706 if (i1==known_symbol_pos(i2)) 00707 the_symbol_is_known=true; 00708 }; 00709 00710 if (!the_symbol_is_known) { 00711 00712 s=(Nfft+Np)*d_reorder(i1)+start_sample; 00713 00714 symbolsc=waveform.mid(s,Nfft); 00715 temp=norm(symbolsc); 00716 power=power+temp*temp; 00717 00718 pz_fft(symbolsc,signal); 00719 00720 //std::cout << "h1=" << h(pilot_carrier1_sub) << "\n"; 00721 //std::cout << "s1=" << signal(pilot_carrier1) << "\n"; 00722 //std::cout << "h2=" << h(pilot_carrier2_sub) << "\n"; 00723 //std::cout << "s2=" << signal(pilot_carrier2) << "\n"; 00724 //std::cout << "pilot_symbol=" << pilot_symbol << "\n"; 00725 00726 if (do_use_pilot_carriers) { 00727 // Common phase error correction (CPEC) 00728 //cpec=pilot_symbol/(signal(pilot_carrier1_sub)/h(pilot_carrier1_sub)+ 00729 // signal(pilot_carrier2_sub)/h(pilot_carrier2_sub)); 00730 00731 cpec=pilot_symbol/(signal(pilot_carrier1)/h(pilot_carrier1_sub)+ 00732 signal(pilot_carrier2)/h(pilot_carrier2_sub)); 00733 00734 cpec=cpec/abs(cpec); 00735 00736 }; 00737 00738 elem_div_out(signal(ix_all),h,demodulator_input); 00739 00740 00741 if (do_use_pilot_carriers) 00742 demodulator_input=demodulator_input*cpec; 00743 00744 00745 for (uint32_t i5=0;i5<length_ix;i5++) { 00746 symbols_out(i4)=demodulator_input(ix_sub(i5)); 00747 i4++; 00748 }; 00749 }; 00750 }; 00751 power=power/((Ns-known_symbol_pos.length())*Nfft); 00752 rms_signal=sqrt(power); 00753 } 00754 00755 00756 void OFDM1::synchronize(cvec &waveform, uint32_t &start_pos,double &f_offset) { 00757 cvec de_spread(train.size()); 00758 00759 uint32_t Nlags; 00760 double max_value; 00761 int start_pos_int, max_index; 00762 00763 Nlags=waveform.length()-train.length()+1; 00764 vec FrequencyIx(Nlags), Criterions(Nlags); 00765 00766 for (uint32_t i1=0; i1<Nlags;i1 ++) { 00767 de_spread=elem_mult(waveform.mid(i1,train.length()),conj(train)); 00768 max_value=max(abs(fft(de_spread,Nfft_sync)),max_index); 00769 FrequencyIx(i1)=max_index; 00770 Criterions(i1)=max_value; 00771 }; 00772 00773 max_value=max(Criterions,start_pos_int); 00774 start_pos=start_pos_int; 00775 f_offset=FrequencyIx(start_pos)/Nfft_sync; 00776 if (f_offset>0.5) 00777 f_offset=f_offset-1; 00778 00779 f_offset=f_offset*25e6; 00780 00781 00782 } 00783 00784 void OFDM1::synchronize(cvec &waveform, uint32_t &start_pos) { 00785 cvec de_spread(train.size()); 00786 00787 uint32_t Nlags; 00788 double max_value; 00789 int start_pos_int; 00790 00791 Nlags=waveform.length()-train.length()+1; 00792 vec Criterions(Nlags); 00793 00794 for (uint32_t i1=0; i1<Nlags;i1 ++) { 00795 de_spread=elem_mult(waveform.mid(i1,train.length()),conj(train)); 00796 max_value=sum(abs(de_spread)); 00797 Criterions(i1)=max_value; 00798 }; 00799 00800 max_value=max(Criterions,start_pos_int); 00801 start_pos=start_pos_int; 00802 00803 00804 } 00805 00806 void OFDM1::interleave_symbols(cvec &symbols, int index) { 00807 00808 cvec symbol; 00809 00810 index=index % symbol_interleave_matrix.rows(); 00811 symbol.set_length(length_ix); 00812 00813 for (uint32_t i1=0;i1<Ns-known_symbol_pos.length();i1++) { 00814 symbol=symbols.mid(i1*length_ix,length_ix); 00815 symbol=symbol(symbol_interleave_matrix.get_row(index)); 00816 symbols.set_subvector(i1*length_ix,symbol); 00817 }; 00818 00819 }; 00820 00821 void OFDM1::de_interleave_symbols(cvec &symbols, int index) { 00822 00823 cvec symbol; 00824 00825 index=index % symbol_de_interleave_matrix.rows(); 00826 symbol.set_length(length_ix); 00827 00828 for (uint32_t i1=0;i1<Ns-known_symbol_pos.length();i1++) { 00829 symbol=symbols.mid(i1*length_ix,length_ix); 00830 symbol=symbol(symbol_de_interleave_matrix.get_row(index)); 00831 symbols.set_subvector(i1*length_ix,symbol); 00832 }; 00833 00834 00835 }; 00836