00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00402 const int oversampling_;
00403 const int num_carr;
00404 const double carr_dist;
00405 const int space;
00406 const int num_guard;
00407
00408 ofdm::FillUpScheme diffDecodingScheme_;
00409
00410
00411
00412
00413
00414 simth::checkedVector<int> ofdmIndex2origIndex_;
00415
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
00448
00449 mod_value linearPhaseCorrectionFactor(int carrier) const;
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 void traceLinearPhaseCorrection();
00463
00464
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
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
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