00001 00032 #include <itpp/comm/ofdm.h> 00033 #include <itpp/base/specmat.h> 00034 #include <itpp/base/operators.h> 00035 #include <itpp/signal/transforms.h> 00036 00037 00038 namespace itpp { 00039 00040 OFDM::OFDM(int inNfft, int inNcp, int inNupsample) 00041 { 00042 set_parameters(inNfft, inNcp, inNupsample); 00043 } 00044 00045 void OFDM::set_parameters(const int inNfft, const int inNcp, const int inNupsample){ 00046 it_assert(inNfft >= 2, "OFDM: Nfft must be >=2."); 00047 it_assert(inNcp >= 0 && inNcp <= inNfft, "OFDM: Ncp must be >=0 and <=Nfft."); 00048 it_assert(inNupsample >= 1 && inNupsample <= 100, "OFDM: Ncp must be >=1 and <=100."); 00049 Nfft = inNfft; 00050 Ncp = inNcp; 00051 Nupsample = inNupsample; 00052 norm_factor = std::sqrt(static_cast<double>(Nupsample*Nfft*Nfft) / (Nfft+Ncp)); 00053 setup_done = true; 00054 } 00055 00056 void OFDM::modulate(const cvec &input, cvec &output){ 00057 it_assert(setup_done == true, "OFDM::modulate: You must set the length of the FFT and the cyclic prefix!"); 00058 const int N = input.length() / Nfft; 00059 it_assert(N*Nfft == input.length(), "OFDM::modulate: Length of input vector is not a multiple of Nfft."); 00060 00061 output.set_length(Nupsample*N*(Nfft+Ncp)); 00062 cvec outtemp(Nfft); 00063 00064 for (int i = 0; i < N; i++) { 00065 outtemp = ifft(concat(input.mid(i*Nfft, Nfft/2), zeros_c(Nfft*(Nupsample-1)), 00066 input.mid(i*Nfft+Nfft/2, Nfft/2))) * norm_factor; 00067 output.replace_mid(Nupsample*(Nfft+Ncp)*i, concat(outtemp.right(Nupsample*Ncp), outtemp)); 00068 } 00069 } 00070 00071 cvec OFDM::modulate(const cvec &input) 00072 { 00073 cvec output; 00074 modulate(input, output); 00075 return output; 00076 } 00077 00078 void OFDM::demodulate(const cvec& input, cvec &output){ 00079 it_assert(setup_done == true, "OFDM::demodulate: You must set the length of the FFT and the cyclic prefix!"); 00080 const int N = input.length() / (Nfft+Ncp) / Nupsample; 00081 it_assert(Nupsample*N*(Nfft+Ncp) == input.length(), "OFDM: Length of input vector is not a multiple of Nfft+Ncp."); 00082 00083 output.set_length(N*Nfft); 00084 // normalize also taking the energy loss into the cyclic prefix into account 00085 for (int i = 0; i < N; i++) { 00086 cvec x = fft(input.mid(Nupsample*(i*(Nfft+Ncp)+Ncp), Nupsample*Nfft)); 00087 output.replace_mid(Nfft*i, concat(x.left(Nfft/2), x.right(Nfft/2)) / norm_factor); 00088 } 00089 } 00090 00091 cvec OFDM::demodulate(const cvec &input){ 00092 cvec output; 00093 demodulate(input, output); 00094 return output; 00095 } 00096 00097 } //namespace itpp
Generated on Sun Dec 9 17:30:26 2007 for IT++ by Doxygen 1.5.4