Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

ofdmreceiver.h

Go to the documentation of this file.
00001 /***************************************************************************
00002                           ofdmreceiver.h  -  description
00003                              -------------------
00004     begin                : Mit Mai 22 2002
00005     copyright            : (C) 2002 by Peter Haase
00006     email                : mail@p-haase.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
00025  *                                                                         *
00026  ***************************************************************************/
00027 
00028 #ifndef OFDMRECEIVER_HEADER
00029 #define OFDMRECEIVER_HEADER
00030 
00031 #include <fstream>
00032 #include <string>
00033 #include <exception>
00034 
00035 #include "signals.h"
00036 #include "fft.h"
00037 #include "channel.h"
00038 #include "misc.h"
00039 
00040 #include "basicdevice.h"
00041 #include "interfaces.h"
00042 #include "modulator.h"
00043 #include "receiver.h"
00044 #include "transmitter.h"
00045 #include "firfilter.h"
00046 #include "propertylist.h"
00047 
00048 
00049 namespace simthlib
00050 {
00051 
00091 class OfdmReceiver : public Receiver
00092 {
00093 
00094   public:
00095   
00109     OfdmReceiver(int deviceID, simth::DeviceSystemIntf* system,
00110          const simth::PropertyList& pl, 
00111          int oversampling, int carr, double guardTime, double dist,
00112                  ofdm::FillUpScheme diffScheme);
00113 
00122     OfdmReceiver(int deviceID, simth::DeviceSystemIntf* system,
00123          const simth::PropertyList& pl);
00124 
00127     ~OfdmReceiver() = 0;
00128                  
00135     virtual void receiveSignal(const simth::TimeSignal& signalSamples, simth::ModSeq* modSeq,
00136                                double* noise=NULL, simth::ModSeq* trans = NULL);
00137     
00141     virtual void updateInputLengths();
00142 
00146     virtual void updateOutputLengths();
00147 
00153     void setNumPhases(int usedPhases);
00154 
00158     bool needNumPhases() const {return needNumPhases_;}
00159 
00172     void setLinearPhaseCorrection(bool state);
00173 
00174     virtual void startOfSimulation();
00175 
00176     virtual void print(std::ostream &os) const;
00177 
00178     typedef simth::ModSeq::value_type mod_value;
00179     typedef simth::PhaseSeq::value_type phase_value;
00180 
00181   protected:
00182 
00183     int numCarrier() const {return num_carr;}
00184     int numGuard() const {return num_guard;}
00185     int oversampling() const {return oversampling_;}
00186     int symbolsPerOfdm() const {return num_carr;}
00187     int samplesPerOfdmSymbol() const {return num_carr * oversampling_ + num_guard;}
00188     int samplesPerSymbol() const {return oversampling_;}
00189     double carrierDistance() const {return carr_dist;}
00195     double oneOverTimeDistance() const;
00196 
00199     bool isLinearPhaseCorrection() const {return isLinearPhaseCorrection_;}
00200 
00205     int numReceivedOfdmSymbols() const {return numReceivedOfdmSymbols_;}
00206 
00212     void linearPhaseCorrection(simth::ModSeq* modulationSymbols) const;
00213 
00214 
00217     void initScramblingVector(ofdm::FillUpScheme mode,simth::checkedVector<int>* vec) const;
00218 
00237     void initOfdm2origVector( );
00238 
00241     ofdm::FillUpScheme diffDecodingScheme() const;
00242 
00245     void diffDecodingScheme(ofdm::FillUpScheme newDiffMode);
00246 
00251     std::pair<int, int> getOfdmBlockDimensions(int sequenceLength) const;
00252 
00253 
00266     int ofdmIndex2origIndex(int ofdmIndex) const;
00267 
00273     int origIndex2ofdmIndex(int origIndex) const;
00274 
00275 
00286     std::pair<int, int> index2position(int ofdmIndex) const;
00287 
00292     int position2index(int timePos, int freqPos) const;
00293 
00294 
00299     int getTimePos(int index) const;
00300 
00305     int getCarrierPos(int index) const;
00306 
00309     void subGuard(const simth::Array<mod_value> &inArray, 
00310           simth::Array<mod_value>* outArray) const;
00311 
00312     void FFT(const simth::Array<mod_value> &inArray, 
00313          simth::Array<mod_value>* outArray) const;
00314 
00315     void fillOfdmSymbol(const simth::TimeSignal& timeSeq, int currBlockNumber);
00316     void flushOfdmSymbol(simth::ModSeq* modSymbols, int currBlock) const;
00317 
00321     int computeNumGuardSamples(double guardTime) const;
00322 
00323     virtual void invariante() const;
00324 
00335     virtual int numTimeSamples(int numModSymbols) const;
00336 
00343     virtual int numModSymbols(int numTimeSamples) const;
00344 
00345 
00349     virtual void transformSignal(const simth::TimeSignal& signalSamples_ptr,
00350                  simth::ModSeq* modSeq);
00351 
00377     virtual void channelEstimation(const simth::ModSeq& modSymbols, 
00378                    simth::ModSeq* transfer) const;
00379 
00384     virtual void noiseEstimation(const simth::ModSeq& modSymbols, 
00385                  double* noise) const;
00386 
00387 
00390     int numPhases( ) const {return numPhases_;}
00391 
00397     void needNumPhases(bool state) {needNumPhases_=state;}
00398 
00399 
00400       private:
00401     // oversampling rate by the IDFT (IFFT) of the received signal:
00402     const int oversampling_;
00403     const int num_carr;      // number of subcarriers
00404     const double carr_dist;  // subcarrier spacing
00405     const int space;         // sampling space = 1
00406     const int num_guard;     // length of guard interval
00407 
00408     ofdm::FillUpScheme diffDecodingScheme_;
00409 
00410     //is used to scramble the output symbols to 
00411     //provide differential
00412     //decoding for different schemes,
00413     //e.g. differential decoding in frequency direction
00414     simth::checkedVector<int> ofdmIndex2origIndex_;
00415     //the inverse of ofdmIndex2origIndex_:
00416     simth::checkedVector<int> origIndex2ofdmIndex_;
00417 
00423     int computeIndex(int col,int row) const;
00424 
00425 
00426     simth::Array<Complex> ofdmVector;
00427     FastFourierTrans fft;
00428   
00432     int numPhases_;
00438     bool needNumPhases_;
00439 
00440     bool isLinearPhaseCorrection_;
00441 
00442     double refArg;
00443     phase_value phaseCorrectionSum;
00444     int phaseCorrectionCounter;
00445 
00446 
00447     /* Returns a complex correction factor for the given carrier index.
00448     */
00449     mod_value linearPhaseCorrectionFactor(int carrier) const;
00450 
00451     /*  Computes a linear phase correction for the current filled
00452         ofdmVector and added this correction to the previous computed
00453         estimation. This could be useful if the received signal was
00454         sent over a channel with time delay (e.g. a WssusChannel). The
00455         receiver does not consider this time delay, therefore the
00456         symbols sustain a multiplication with a complex factor in the
00457         frequency domain. This complex factor depends linearly on the
00458         freqeuncy, i.e. the number of the subcarrier. This function
00459         computes this factor using the complex symbols filled into
00460         ofdmVector.
00461     */
00462     void traceLinearPhaseCorrection();
00463 
00464     /* For the sake of computational efficiency, store the number of received OFDM symbols.
00465      */
00466     int numReceivedOfdmSymbols_;
00467 
00468     
00469 };
00470 
00471 
00472 
00473 inline
00474 ofdm::FillUpScheme OfdmReceiver::diffDecodingScheme() const
00475 {
00476   return diffDecodingScheme_;
00477 }
00478 
00479 inline
00480 void OfdmReceiver::diffDecodingScheme(ofdm::FillUpScheme newDiffMode)
00481 {
00482   diffDecodingScheme_ = newDiffMode;
00483   initOfdm2origVector();
00484 }
00485 
00486 inline
00487 std::pair<int, int> OfdmReceiver::getOfdmBlockDimensions(int sequenceLength) const
00488 {
00489   int dim2 = numCarrier();
00490   if(SECURITY) {
00491     if(sequenceLength % numCarrier() != 0) {
00492       throw std::runtime_error("std::pair<int, int> OfdmReceiver::getOfdmBlockDimensions(int sequenceLength) const : error 1");
00493     }
00494   }
00495   int dim1 = sequenceLength/dim2;
00496   return std::pair<int, int>(dim1,dim2);
00497 }
00498 
00499 inline
00500 std::pair<int,int> OfdmReceiver::index2position(int index) const
00501 {
00502   return ofdm::index2position(index,numCarrier());
00503 }
00504 
00505 
00506 inline
00507 int OfdmReceiver::position2index(int timePos, int carrierPos) const
00508 {
00509   return ofdm::position2index(timePos,carrierPos,numCarrier());
00510 }
00511 
00512 
00513 inline 
00514 int OfdmReceiver::ofdmIndex2origIndex(int ofdmIndex) const
00515 {
00516 #if DEBUG != 0
00517   if(unsigned(ofdmIndex) >= ofdmIndex2origIndex_.size()) {
00518     throw std::logic_error("int OfdmReceiver::ofdmIndex2origIndex(int ofdmIndex) const : "
00519                            "ofdmIndex >= ofdmIndex2origIndex_.size()");
00520   }
00521 #endif
00522   return ofdmIndex2origIndex_[ofdmIndex];
00523 }
00524 
00525 inline
00526 int OfdmReceiver::origIndex2ofdmIndex(int origIndex) const
00527 {
00528 #if DEBUG != 0
00529   if(unsigned(origIndex) >= origIndex2ofdmIndex_.size()) {
00530     throw std::logic_error("int OfdmReceiver::origIndex2ofdmIndex(int origIndex) const : "
00531                            "origIndex >= origIndex2ofdmIndex_.size()");
00532   }
00533 #endif
00534   return origIndex2ofdmIndex_[origIndex];
00535 }
00536 
00537 
00538 inline
00539 int OfdmReceiver::getTimePos(int index) const
00540 {
00541 
00542   if(DEBUG) {
00543     if (index<0) {
00544       throw std::runtime_error("int OfdmReceiver::getTimePos(int index) : error 1");
00545     }
00546   }
00547 
00548   return index / numCarrier();
00549 
00550 }
00551 
00552 
00553 inline
00554 int OfdmReceiver::getCarrierPos(int ofdmIndex) const
00555 {
00556 
00557   if(DEBUG) {
00558     if (ofdmIndex<0) {
00559       throw std::runtime_error("int OfdmReceiver::getTimePos(int index) : error 1");
00560     }
00561   }
00562   return ofdmIndex % numCarrier();
00563 }
00564 
00565 
00566 
00567 inline void OfdmReceiver::FFT(const simth::Array<mod_value> &inArray, simth::Array<mod_value>* outArray) const
00568 {
00569   fft.FFT(inArray, outArray, oversampling(), space);
00570   if(DEBUG) {
00571     if(int(outArray->size())!=num_carr) {
00572       throw std::logic_error("inline void OfdmReceiver::FFT(const simth::Array<mod_value> &inArray, simth::Array<mod_value>* outArray) const : error 1");
00573     }
00574   }
00575 }
00576 
00577 
00578 inline void OfdmReceiver::invariante() const
00579 {
00580   if(DEBUG) {
00581     if(num_guard > (num_carr * oversampling())) {
00582       throw std::logic_error("inline void OfdmReceiver::invariante() : error 1");
00583     }
00584     if(int(ofdmVector.size()) != num_carr) {
00585       throw std::logic_error("inline void OfdmReceiver::invariante() : error 3");
00586     }
00587   }
00588 }
00589 
00590 
00591 
00594 class OfdmReceiverNoEstimation : public OfdmReceiver
00595 {
00596   private:
00597 
00598   protected:
00599 
00600   public:
00601 
00602     OfdmReceiverNoEstimation(int deviceID, simth::DeviceSystemIntf* system,
00603                  const simth::PropertyList& pl, 
00604                  int oversampling, int carr,
00605                  double guardTime, double dist,
00606                  ofdm::FillUpScheme diffScheme);
00607     OfdmReceiverNoEstimation(int deviceID, simth::DeviceSystemIntf* system,
00608                  const simth::PropertyList& pl);
00609 
00610     void print(std::ostream &os) const;
00611 };
00612 
00613 
00614 
00615 
00618 class OfdmReceiverIdealEstimation : public OfdmReceiver
00619 {
00620   private:
00621 
00622     //Pointer to channel, is used for ideal channel estimation:
00623     const Channel* channel;
00624 
00625   protected:
00626 
00631     virtual void channelEstimation(const simth::ModSeq& modSymbols, 
00632                    simth::ModSeq* transfer) const;
00633 
00636     virtual void noiseEstimation(const simth::ModSeq& modSymbols, double* noise) const;
00637 
00652     void fillTransfer(simth::ModSeq* transfer, int timePos, int modPos) const;
00653 
00654     void estimateTransfer(int timePos,  simth::FreqSignal* transferFactor) const;
00655 
00656   public:
00657 
00661     OfdmReceiverIdealEstimation(int deviceID, simth::DeviceSystemIntf* system,
00662                 const simth::PropertyList& pl, 
00663                 int oversampling, int carr, double guardTime, double dist,
00664                                 ofdm::FillUpScheme diffScheme, const Channel* channelPtr);
00665 
00667     OfdmReceiverIdealEstimation(int deviceID, simth::DeviceSystemIntf* system,
00668                 const simth::PropertyList& pl);
00669 
00672     //void startOfSimulation();
00673 
00674     void print(std::ostream &os) const;
00675 };
00676 
00677 
00678 inline void OfdmReceiverIdealEstimation::estimateTransfer(int timePos, simth::FreqSignal* transferFactor) const
00679 {
00680   if(channel == NULL) {
00681     throw std::runtime_error("void OfdmReceiver::estimateTransfer(int timePos, "
00682                              "FreqSignal* transferFactor) const : connection to channel is not set");
00683   }
00684   if(transferFactor == NULL) {
00685     throw std::logic_error("void OfdmReceiver::estimateTransfer(int timePos, simth::FreqSignal* "
00686                            "transferFactor) const : error 2");
00687   }
00688 
00689   if(int(transferFactor->size()) != numCarrier()) {
00690     transferFactor->resize(numCarrier());
00691   }
00692   if(transferFactor->rAttributes().deltaF() != carrierDistance()) {
00693     transferFactor->wAttributes().setDeltaF(carrierDistance());
00694   }
00695   channel->getTransfer(timePos,*transferFactor);
00696 }
00697 
00698 
00699 
00700 }
00701 
00702 #endif

Generated on Tue Aug 9 14:35:11 2005 for simtheticlib by  doxygen 1.4.1