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
00029 #ifndef TRANSMITTER_HEADER
00030 #define TRANSMITTER_HEADER
00031
00032 #include <fstream>
00033 #include <string>
00034 #include <exception>
00035
00036 #include "signals.h"
00037 #include "fft.h"
00038 #include "channel.h"
00039 #include "misc.h"
00040
00041 #include "basicdevice.h"
00042 #include "interfaces.h"
00043 #include "modulator.h"
00044
00045
00046 namespace simthlib
00047 {
00048
00049 class Transmitter;
00050
00051 std::ostream& operator<<(std::ostream &os, const Transmitter &tr);
00052
00053
00054
00055
00056
00057
00064 class Transmitter : public simth::Device
00065 {
00066 public:
00070 Transmitter(int deviceID, simth::DeviceSystemIntf* system,
00071 const simth::PropertyList& pl);
00072
00079 virtual void makeSignal(const simth::ModSeq& modSeq,
00080 simth::TimeSignal* outSignal) = 0;
00081
00082
00083
00084
00085
00086
00087 virtual void process();
00088
00089 virtual void print(std::ostream &os) const;
00090
00091
00092 static void init(const std::string fileName, simth::Device** dev,
00093 simth::DeviceSystemIntf* sysPtr, int ID,
00094 const std::string& regionQualifier = "");
00095
00096 };
00097
00098
00099
00133 namespace ofdm
00134 {
00135
00136 enum FillUpScheme {TIME, TIME_SNAKE, FREQ, FREQ_SNAKE};
00137
00141 ofdm::FillUpScheme string_to_diffscheme(const std::string &s);
00142
00143 void initFillUpScheme(FillUpScheme mode,
00144 int numOfdmSymbols,
00145 int numCarrier, simth::checkedVector<int>* vec);
00146
00154 std::pair<int,int> index2position(int index,int numCarrier);
00155
00158 int position2index(int timePos, int carrierPos, int numCarrier);
00159
00160 }
00161
00162
00199 class OfdmTransmitter : public Transmitter
00200 {
00201 private:
00202 const int oversampling;
00203 const int num_carr;
00204 const double carr_dist;
00205 const int space;
00206 double delta_t;
00207 const int num_guard;
00208
00209 ofdm::FillUpScheme diffDecodingScheme_;
00210
00211
00212
00213
00214 simth::checkedVector<int> ofdmIndex2origIndex_;
00215
00216
00217 simth::Array<Complex> ofdmVector;
00218 FastFourierTrans fft;
00219
00220 virtual void fillOfdmSymbol(const simth::ModSeq& modulationSymbols, int blockNumber);
00221
00222
00223 protected:
00224
00229 virtual double deltaT() const;
00230
00231 int numCarrier() const {return num_carr;}
00232 int symbolsPerOfdm() const {return num_carr;}
00233 int samplesPerOfdmSymbol() const {return num_carr * oversampling + num_guard;}
00234 int samplesPerSymbol() const {return oversampling;}
00235 int numGuard() const {return num_guard;}
00236 double carrierDistance() const {return carr_dist;}
00237
00238
00241 void initScramblingVector(ofdm::FillUpScheme mode,simth::checkedVector<int>* vec) const;
00242
00261 void initOfdm2origVector( );
00262
00265 ofdm::FillUpScheme diffDecodingScheme() const {return diffDecodingScheme_;}
00266
00279 int ofdmIndex2origIndex(int ofdmIndex) const;
00280
00281
00289 std::pair<int, int> index2position(int ofdmIndex) const;
00290
00293 int position2index(int timePos, int freqPos) const;
00294
00295
00296 void addGuard(const simth::Array<Complex> &inArray, simth::Array<Complex>* outArray) const;
00297
00298 void IFFT(const simth::Array<Complex> &freqArray, simth::Array<Complex>* timeArray) const;
00299
00300 void transmitOfdmSymbol(simth::TimeSignal* timeSig,int currBlockNumber) const;
00301
00307 double oneOverTimeDistance() const;
00308
00312 int computeNumGuardSamples(double guardTime) const;
00313
00314 void invariante() const;
00315
00316 int numTimeSamples(int numModSymbols) const;
00317
00318 public:
00329 OfdmTransmitter(int deviceID, simth::DeviceSystemIntf* system,
00330 const simth::PropertyList& pl,
00331 int oversampling, int carrier,
00332 double guardTime, double dist);
00333
00340 OfdmTransmitter(int deviceID, simth::DeviceSystemIntf* system,
00341 const simth::PropertyList& pl);
00342
00343 virtual ~OfdmTransmitter(){};
00344
00345
00346 virtual void makeSignal(const simth::ModSeq& modSeq, simth::TimeSignal* outSignal);
00347
00348 virtual void updateInputLengths();
00349 virtual void updateOutputLengths();
00350
00351
00352
00353 virtual void print(std::ostream &os) const;
00354 };
00355
00356
00357
00358
00359 inline void OfdmTransmitter::invariante() const
00360 {
00361 if(DEBUG) {
00362 if(oversampling <= 0) {
00363 throw std::logic_error("inline OfdmTransmitter::invariante() : error 1");
00364 }
00365 if(num_carr <= 0) {
00366 throw std::logic_error("inline OfdmTransmitter::invariante() : error 2");
00367 }
00368 if(int(ofdmVector.size()) != num_carr) {
00369 throw std::logic_error("inline OfdmTransmitter::invariante() : error 3");
00370 }
00371 if(num_guard <= 0) {
00372 throw std::logic_error("inline OfdmTransmitter::invariante() : error 4");
00373 }
00374 if(carr_dist <= 0) {
00375 throw std::logic_error("inline OfdmTransmitter::invariante() : error 5");
00376 }
00377
00378 }
00379 }
00380
00381
00382 inline
00383 std::pair<int,int> OfdmTransmitter::index2position(int index) const
00384 {
00385 return ofdm::index2position(index,numCarrier());
00386 }
00387
00388
00389 inline
00390 int OfdmTransmitter::position2index(int timePos, int carrierPos) const
00391 {
00392 return ofdm::position2index(timePos,carrierPos,numCarrier());
00393 }
00394
00395
00396 inline
00397 int OfdmTransmitter::ofdmIndex2origIndex(int ofdmIndex) const
00398 {
00399 #if DEBUG != 0
00400 if(unsigned(ofdmIndex) >= ofdmIndex2origIndex_.size()) {
00401 throw std::logic_error("int OfdmTransmitter::ofdmIndex2origIndex(int ofdmIndex) const : "
00402 "ofdmIndex >= ofdmIndex2origIndex_.size()");
00403 }
00404 #endif
00405 return ofdmIndex2origIndex_[ofdmIndex];
00406 }
00407
00408
00409 inline void OfdmTransmitter::IFFT(const simth::Array<Complex> &inArray, simth::Array<Complex>* outArray) const
00410 {
00411 fft.IFFT(inArray, outArray, space, oversampling);
00412 }
00413
00414
00415 inline double OfdmTransmitter::deltaT() const
00416 {
00417 invariante();
00418 return delta_t;
00419 }
00420
00421
00424 class SingleCarrierTransmitter : public Transmitter
00425 {
00426
00427 public:
00437 SingleCarrierTransmitter(int deviceID, simth::DeviceSystemIntf* system,
00438 const simth::PropertyList& pl);
00439
00440 virtual ~SingleCarrierTransmitter(){};
00441
00444 virtual void makeSignal(const simth::ModSeq& modSeq,
00445 simth::TimeSignal* outSignal);
00446
00447 virtual void updateInputLengths();
00448 virtual void updateOutputLengths();
00449
00450 virtual void print(std::ostream &os) const;
00451
00452
00453 protected:
00454
00457 double modulationSymbolDistance() const {return modulationSymbolDistance_;}
00458
00461 int samplesBetweenModulationSymbols() const {return samplesBetweenModulationSymbols_;}
00462
00467 double deltaT() const {return transmitPulse.rAttributes().deltaT();}
00468
00471 int numSamplesOfPulse() const {return transmitPulse.size();}
00472
00477 int numTimeSamples(int numModSymbols) const;
00478 private:
00479
00480 const double modulationSymbolDistance_;
00481 int samplesBetweenModulationSymbols_;
00482
00483 simth::TimeSignal::storage_type transmitPulse;
00484 };
00485
00486
00487 }
00488
00489 #endif
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523