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 MODULATIONSCHEMES_H
00029 #define MODULATIONSCHEMES_H
00030
00031
00032 #include <complex>
00033 #include <vector>
00034 #include <simthetic/phbib.h>
00035 #include <simtheticlib/modulationmodes.h>
00036
00037
00038 namespace simthlib
00039 {
00040
00089 class ConstellationDiagram
00090 {
00091 private:
00092
00093
00094 const unsigned bitsPerSymbol;
00095 const unsigned modulationValency;
00096
00097
00098 std::vector<simth::Complex> complStates;
00099
00100 protected:
00101
00107 virtual void setComplSymbols(unsigned symbolIndex,
00108 const simth::Complex& newValue);
00109
00110
00123 virtual void initComplSymbols()=0;
00124
00125
00126 public:
00127
00131 ConstellationDiagram(unsigned bitsPerSymb);
00132
00135 virtual ~ConstellationDiagram(){};
00136
00140 unsigned getBitsPerSymbol() const {return bitsPerSymbol;}
00141
00142
00149 inline const simth::Complex& getComplSymbol(unsigned symbolIndex) const;
00150
00151
00157 unsigned getNumStates() const {return modulationValency;}
00158
00163 void scaleConstellation(const simth::Complex& scaleFactor);
00164
00168 const simth::Complex& hardDecision(const simth::Complex& r) const;
00169
00171 virtual void print(std::ostream &os, bool gnuplotFormat = false) const;
00172
00173 };
00174
00175
00176 inline const simth::Complex& ConstellationDiagram::getComplSymbol(unsigned modIndex) const
00177 {
00178 if(DEBUG) {
00179 if ( modIndex >= modulationValency ) {
00180 throw std::out_of_range("Complex ConstellationDiagram::getComplSymbol(int modIndex) modIndex = "
00181 +simth::i2string(modIndex));
00182 }
00183 }
00184 return complStates[modIndex];
00185 }
00186
00187
00188
00189
00192 class QamConstellationDiagram : public ConstellationDiagram
00193 {
00194
00195 private:
00196 unsigned bitsPerRealPart;
00197 unsigned bitsPerImPart;
00198
00199 public:
00203 QamConstellationDiagram(unsigned bitsPerSymbol);
00204
00205 virtual void initComplSymbols();
00206
00211 static unsigned getRealBits(unsigned bitsPerSymbol);
00212
00217 static unsigned getImBits(unsigned bitsPerSymbol);
00218
00219 };
00220
00227 class PhaseAmplitudeConstellationDiagram : public ConstellationDiagram
00228 {
00229
00230 struct PolarComplex
00231 {
00232 double ampl;
00233 double phase;
00234 };
00235
00236
00237 double deltaPhase_;
00238
00239
00240 std::vector<PhaseAmplitudeConstellationDiagram::PolarComplex> polarStates;
00241
00242
00243 int bitsPerAmpl_;
00244 int bitsPerPhase_;
00245
00246 int numAmplitudes_;
00247 int numPhases_;
00248
00249 protected:
00250
00251 virtual void setComplSymbols(int symbolIndex,simth::Complex newValue);
00252
00253 void setDeltaPhase(double newDeltaPhase);
00254
00255 public:
00256
00257 PhaseAmplitudeConstellationDiagram(int bitsPerAmpl, int bitsPerPhase);
00258
00259
00260
00261
00262
00263 int bitsPerAmpl() const {return bitsPerAmpl_;}
00264 int numAmplitudes() const {return numAmplitudes_;}
00265
00266
00267
00268
00269
00270 int bitsPerPhase() const {return bitsPerPhase_;}
00271 int numPhases() const {return numPhases_;}
00272
00277 virtual double deltaPhase( ) const {return deltaPhase_;}
00278
00282 double getPhase(unsigned symbolIndex) const;
00283
00287 double getAmplitude(unsigned symbolIndex) const;
00288
00292 int getSymbolIndex(int amplIndex, int phaseIndex) const {return (amplIndex<<bitsPerPhase())+phaseIndex;}
00293
00297 int getAmplIndex(int symbolIndex) const {return symbolIndex>>bitsPerPhase();}
00298
00302 int getPhaseIndex(int symbolIndex) const {return symbolIndex||(1<<bitsPerPhase())-1;}
00303
00304 };
00305
00306
00307
00308 inline double PhaseAmplitudeConstellationDiagram::getPhase(unsigned modIndex) const
00309 {
00310 if(DEBUG) {
00311 if( (modIndex >= getNumStates() )) {
00312 throw std::out_of_range("Complex PhaseAmplitudeConstellationDiagram::getComplSymbol(int modIndex) modIndex = "
00313 +simth::i2string(modIndex));
00314 }
00315 }
00316 return (polarStates[modIndex]).phase;
00317 }
00318
00319 inline double PhaseAmplitudeConstellationDiagram::getAmplitude(unsigned modIndex) const
00320 {
00321 if(DEBUG) {
00322 if( (modIndex >= getNumStates() )) {
00323 throw std::out_of_range("Complex PhaseAmplitudeConstellationDiagram::getComplSymbol(int modIndex) modIndex = "
00324 +simth::i2string(modIndex));
00325 }
00326 }
00327 return (polarStates[modIndex]).ampl;
00328 }
00329
00330
00331
00335 class PskConstellationDiagram : public PhaseAmplitudeConstellationDiagram
00336 {
00337 virtual void initComplSymbols();
00338
00339 public:
00340
00344 PskConstellationDiagram(int bitsPerSymbol);
00345
00346 };
00347
00348
00351 class ApskConstellationDiagram : public PhaseAmplitudeConstellationDiagram
00352 {
00353 virtual void initComplSymbols();
00354
00355
00356 double a;
00357
00358 double addend;
00359
00360
00361 double normalizeFactor;
00362
00363 int getPhaseIndex(int symbolIndex) const;
00364 int getAmplitudeIndex(int symbolIndex) const;
00365
00366 public:
00367
00371 ApskConstellationDiagram(int bitsPerSymbol, detect_type mode);
00372
00376 ApskConstellationDiagram(int bitsPerSymbol, double amplFactor, double amplAddend=0.0);
00377
00381 ApskConstellationDiagram(int bitsPerAmpl, int bitsPerPhase, double amplFactor, double amplAddend=0.0);
00382
00383
00387 double getAmplFactor() const {return a;}
00391 double getAmplAddend() const {return addend;}
00392
00397 static int computeAmplitudeBits(int bitsPerSymbol);
00398
00403 static int computePhaseBits(int bitsPerSymbol);
00404
00408 static double computeAmplitudeFactor(int bitsPerState, detect_type mode);
00409
00414 static double computeAmplitudeAddend(int bitsPerState, detect_type mode);
00415
00416
00417 };
00418
00419
00420
00421
00422
00423
00424 }
00425
00426 #endif