00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef CHANNEL_HEADER
00029 #define CHANNEL_HEADER
00030
00031 #include <iostream>
00032 #include <fstream>
00033 #include <complex>
00034 #include <memory>
00035
00036 #include <phbib.h>
00037 #include <phrand.h>
00038 #include <signals.h>
00039 #include <basicdevicefactory.h>
00040 #include <basicdevice.h>
00041 #include <interfaces.h>
00042
00043 namespace
00044 {
00045 const double DELAY_THRESHOLD = 0.001;
00046 }
00047
00048 namespace simthlib
00049 {
00050 using simth::Complex;
00051
00052
00055
00056
00057 class DelayProfile;
00058
00059 class Channel;
00060 std::ostream& operator<<(std::ostream &os, const Channel &cha);
00061
00062
00070 class Channel : public simth::Device
00071 {
00073 double noise;
00074
00076 simth::GaussRng *gauss;
00077
00078 protected:
00079
00081 double getGauss() const { return gauss->get_inl();}
00082
00083 public:
00084
00092 Channel(int id, simth::DeviceSystemIntf *s, const simth::PropertyList& pl,
00093 double noise = 1.0);
00094
00097 virtual ~Channel() {delete gauss;}
00098
00105 void setNoisePower(double n = 1.0);
00106
00110
00111
00115 void setSNR(double snr);
00116
00117
00120 double getNoisePower() const { return noise; }
00121
00134 virtual void getTransfer(int relative_time, simth::FreqSignal& trans) const =0;
00135
00138 virtual void transmit(const simth::TimeSignal &sym, simth::TimeSignal* outsym) =0;
00139
00140 virtual void updateInputLengths();
00141 virtual void updateOutputLengths();
00142
00143 virtual void process();
00144
00145 virtual void startOfSimulation();
00146
00147 virtual void print(std::ostream &os) const ;
00148
00149 static void init(const std::string fileName, simth::Device** dev,
00150 simth::DeviceSystemIntf* sysPtr, int ID,
00151 const std::string& regionQualifier = "");
00152 };
00153
00154
00155
00156
00157 inline void Channel::setNoisePower(double n)
00158 {
00159 noise = n;
00160 gauss->setVariance(n/2.0);
00161 }
00162
00163
00164 inline void Channel::setSNR(double snr)
00165 {
00166 double n = simth::db2reciprocalLinearPowerRatio(snr);
00167 setNoisePower(n);
00168 }
00169
00170
00171
00176 class IdealChannel : public Channel
00177 {
00178
00179 public:
00181 IdealChannel(int id, simth::DeviceSystemIntf *s, const simth::PropertyList& pl)
00182 : Channel(id, s, pl, 0){}
00183
00195 virtual void getTransfer(int relative_time, simth::FreqSignal& trans) const;
00196
00198 virtual void transmit(const simth::TimeSignal &sym, simth::TimeSignal* outsym);
00199 virtual void print(std::ostream &os) const;
00200 };
00201
00202 inline void IdealChannel::transmit(const simth::TimeSignal &sym, simth::TimeSignal* outsym)
00203 {
00204 if(outsym == NULL) {
00205 throw std::runtime_error("void IdealChannel::transmit(const simth::TimeSignal &sym, simth::TimeSignal* outsym)");
00206 }
00207 double deltaTime = sym.rAttributes().deltaT();
00208 if(outsym->rAttributes().deltaT() != deltaTime) {
00209 outsym->wAttributes().setDeltaT(deltaTime);
00210 }
00211 size_t size = sym.size();
00212 if(outsym->size() != size) {
00213 outsym->resize(size);
00214 }
00215
00216 (*outsym) = sym;
00217 }
00218
00219 inline void IdealChannel::print(std::ostream &os) const
00220 {
00221
00222 std::ios::fmtflags oldSettings = os.flags();
00223 Channel::print(os);
00224 os.width(15);
00225 os<<std::endl<<"# channel type: no channel";
00226 os.width(15);
00227 os.setf(oldSettings);
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00263 class AWGNChannel : public Channel
00264 {
00265
00266
00267
00268 protected:
00269
00270 public:
00272 AWGNChannel(int id, simth::DeviceSystemIntf *s, const simth::PropertyList& pl,
00273 double n=0) : Channel(id, s, pl, n) { }
00274
00276 virtual ~AWGNChannel() {}
00277
00289 virtual void getTransfer(int relative_time, simth::FreqSignal& trans) const;
00290
00292 void transmit(const simth::TimeSignal &sym, simth::TimeSignal* outsym);
00293
00294 virtual void print(std::ostream &os) const;
00295 };
00296
00297
00298 inline void AWGNChannel::print(std::ostream &os) const
00299 {
00300
00301 std::ios::fmtflags oldSettings = os.flags();
00302 Channel::print(os);
00303 os.width(15);
00304 os<<std::endl<<"# channel type: AWGN cannel";
00305 os.setf(oldSettings);
00306 }
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00346 class FadingChannel : public Channel
00347 {
00348
00349 public:
00350
00355 enum fix_type {
00357 FIXED,
00359 UNFIXED };
00360
00361
00364 FadingChannel(int id, simth::DeviceSystemIntf *s,
00365 const simth::PropertyList& pl,
00366 fix_type fix=UNFIXED);
00367
00369 virtual ~FadingChannel();
00370
00372 int IsFixed() const { return (fixed == FIXED); }
00373
00375 virtual void refresh();
00376
00388 virtual void getTransfer(int relative_time, simth::FreqSignal& trans) const;
00389
00391 void transmit(const simth::TimeSignal &sym, simth::TimeSignal* outsym);
00392
00395 virtual void startOfSimulation();
00396
00397 virtual void print(std::ostream &os) const;
00398
00399 protected:
00400
00402 fix_type fixed;
00403
00405 double sigma;
00406
00407
00408
00409
00410
00411
00413 simth::RayleighRng *ray;
00414
00416 simth::Array<simth::Complex> transfer;
00417
00418
00419 };
00420
00424 class CmplFadingChannel : public FadingChannel
00425 {
00426 private:
00427 simth::GaussRng real;
00428 simth::GaussRng imag;
00429
00430 public:
00432 CmplFadingChannel(int id, simth::DeviceSystemIntf *s,
00433 const simth::PropertyList& pl,
00434 fix_type fix=UNFIXED);
00435
00437 virtual ~CmplFadingChannel();
00438
00440 void refresh();
00441 };
00442
00443
00444
00445
00446
00447
00448
00489 class WssusChannel : public Channel
00490 {
00491 public:
00492
00493
00494
00495 private:
00496
00498 double rice_factor;
00499
00501 int num_paths;
00502
00504 double *phase;
00505
00507 double *dopp_freq;
00508
00510 int *delay;
00511
00513 double *delta_phi;
00514
00516 double delta_t;
00517
00519 simth::Array<simth::Complex> prevsym;
00520
00525 bool firstSequence;
00526
00528 int roundTimeToSamples(double value) const;
00529
00530
00531 enum Normalization_Mode {
00533 STD,
00547 TIME,
00563 FREQ};
00565 Normalization_Mode normMode;
00567 double normFactor;
00569 void resetNormalizeFactor();
00571 double freqDist;
00573 int numFreqs;
00574
00575
00576
00577
00578 mutable simth::FreqSignal::storage_type cacheTransfer;
00580 mutable int cacheTime;
00581 mutable bool isTransferCacheValid;
00582
00583
00584
00585 int interval[6];
00587 simth::Array<simth::Complex> savesym;
00588
00590
00591
00592
00593
00594
00595
00596 protected:
00597
00602 virtual double maxDelay() const = 0;
00603
00607 virtual double diceNewDelay() const = 0;
00611 virtual double diceNewPhase() const = 0;
00612
00616 virtual double diceNewDopplerFreq() const = 0;
00617
00618
00619 public:
00632 WssusChannel(int id, simth::DeviceSystemIntf *s,
00633 const simth::PropertyList& pl,
00634 double n=1.0);
00635
00637 virtual ~WssusChannel();
00638
00639
00641 void refresh();
00642
00662 virtual void getTransfer(int relative_time, simth::FreqSignal& trans) const;
00663
00669 void transmit(const simth::TimeSignal &insym, simth::TimeSignal* outsym);
00670
00674 void setRiceFactor(double rf);
00675
00679 void setRiceFactor_dB(double rf);
00680
00681
00683 virtual void setCohTime(double tc)=0;
00684
00686 virtual void setCohBandw(double bc)=0;
00687
00691 double GetDeltaT() {return delta_t;}
00692
00694 void adjustDeltaT(double newDeltaT);
00695
00698 void setTimeNormalization();
00699
00704 void setFreqNormalization(double freqDist, int numFreqs);
00705
00708
00709
00712
00713
00716 virtual void startOfSimulation();
00717
00718
00719 virtual void print(std::ostream &os) const;
00720
00721 };
00722
00723
00724 inline int WssusChannel::roundTimeToSamples(double value) const
00725 {
00726 if(DEBUG) {
00727 int returnValue = int(value / delta_t + 0.5);
00728 if(returnValue < 0) {
00729 std::cerr<<std::endl<<"delta_t: "<<delta_t<<" value: "<<value<<std::endl;
00730 throw std::out_of_range("inline int WssusChannel::roundTimeToSamples(double value) : error 1"
00731 " (deltaT to small !?)");
00732 }
00733 return returnValue;
00734 }
00735 return int(value / delta_t + 0.5);
00736 }
00737
00738
00739
00740
00741
00748 class WssusChannelJakesUniform : public WssusChannel
00749 {
00750 private:
00752 simth::UniformRng* uniformPhaseRng;
00754 simth::JakesRng* jakesDoppFreqRng;
00755 protected:
00756 virtual double diceNewPhase() const;
00757 virtual double diceNewDopplerFreq() const;
00758 public:
00765 WssusChannelJakesUniform(int id, simth::DeviceSystemIntf *s,
00766 const simth::PropertyList& pl,
00767 double max_doppler);
00768 virtual ~WssusChannelJakesUniform();
00769
00770 virtual void setCohTime(double tc);
00771
00772 virtual void print(std::ostream &os) const;
00773
00774 };
00775
00776
00779 class WssusChannelDelayProfile : public WssusChannelJakesUniform
00780 {
00781 private:
00782
00784 DelayProfile* delayProfile;
00785
00786 protected:
00787
00791 virtual double maxDelay() const;
00792
00796 virtual double diceNewDelay() const;
00797
00798
00802 void resetDelayProfile(std::auto_ptr<DelayProfile> newProfile);
00803
00804 public:
00814 WssusChannelDelayProfile(int id, simth::DeviceSystemIntf *s,
00815 const simth::PropertyList& pl,
00816 double max_doppler,
00817 std::auto_ptr<DelayProfile> profile);
00818
00819 ~WssusChannelDelayProfile( );
00820
00821 virtual void print(std::ostream &os) const;
00822 };
00823
00824
00847 class WssusChannelExpDelay : public WssusChannelDelayProfile
00848 {
00849
00850 public:
00859 WssusChannelExpDelay(int id, simth::DeviceSystemIntf *s,
00860 const simth::PropertyList& pl,
00861 double max_doppler, double delayAttenuation,
00862 double max_delay);
00863
00871 WssusChannelExpDelay(int id, simth::DeviceSystemIntf *s,
00872 const simth::PropertyList& pl);
00873
00874
00875 virtual void setCohBandw(double bc);
00876
00877 };
00878
00879
00882 class WssusChannelBU : public WssusChannelDelayProfile
00883 {
00884
00885 public:
00891 WssusChannelBU(int id, simth::DeviceSystemIntf *s,
00892 const simth::PropertyList& pl);
00893
00894
00895 virtual void setCohBandw(double bc);
00896 };
00897
00898
00901 class WssusChannelHt : public WssusChannelDelayProfile
00902 {
00903 public:
00904
00910 WssusChannelHt(int id, simth::DeviceSystemIntf *s, const simth::PropertyList& pl);
00911
00912
00913 virtual void setCohBandw(double bc);
00914 };
00915
00916
00922 class WssusChannelScattering : public WssusChannelExpDelay
00923 {
00924 public:
00930 WssusChannelScattering(int id, simth::DeviceSystemIntf *s,
00931 const simth::PropertyList& pl);
00932 };
00933
00934
00941 class WssusChannelFreqTimeCorr : public WssusChannelExpDelay
00942 {
00943 public:
00950 WssusChannelFreqTimeCorr(int id, simth::DeviceSystemIntf *s,
00951 const simth::PropertyList& pl);
00952 };
00953
00960 class WssusChannelRA : public WssusChannelExpDelay
00961 {
00962 public:
00968 WssusChannelRA(int id, simth::DeviceSystemIntf *s,
00969 const simth::PropertyList& pl);
00970 };
00971
00974 class WssusChannelTu : public WssusChannelExpDelay
00975 {
00976 public:
00982 WssusChannelTu(int id, simth::DeviceSystemIntf *s,
00983 const simth::PropertyList& pl);
00984 };
00985
00986
00987
00988
00989
00990
00992
00993 }
00994
00995 #endif