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 virtual ~QamConstellationDiagram();
00205
00206 virtual void initComplSymbols();
00207
00212 static unsigned getRealBits(unsigned bitsPerSymbol);
00213
00218 static unsigned getImBits(unsigned bitsPerSymbol);
00219
00220 };
00221
00228 class PhaseAmplitudeConstellationDiagram : public ConstellationDiagram
00229 {
00230
00231 struct PolarComplex
00232 {
00233 double ampl;
00234 double phase;
00235 };
00236
00237
00238 double deltaPhase_;
00239
00240
00241 std::vector<PhaseAmplitudeConstellationDiagram::PolarComplex> polarStates;
00242
00243
00244 int bitsPerAmpl_;
00245 int bitsPerPhase_;
00246
00247 int numAmplitudes_;
00248 int numPhases_;
00249
00250 protected:
00251
00252 virtual void setComplSymbols(int symbolIndex,simth::Complex newValue);
00253
00254 void setDeltaPhase(double newDeltaPhase);
00255
00256 public:
00257
00258 PhaseAmplitudeConstellationDiagram(int bitsPerAmpl, int bitsPerPhase);
00259 virtual ~PhaseAmplitudeConstellationDiagram();
00260
00261
00262
00263
00264 int bitsPerAmpl() const {return bitsPerAmpl_;}
00265 int numAmplitudes() const {return numAmplitudes_;}
00266
00267
00268
00269
00270
00271 int bitsPerPhase() const {return bitsPerPhase_;}
00272 int numPhases() const {return numPhases_;}
00273
00278 virtual double deltaPhase( ) const {return deltaPhase_;}
00279
00283 double getPhase(unsigned symbolIndex) const;
00284
00288 double getAmplitude(unsigned symbolIndex) const;
00289
00293 int getSymbolIndex(int amplIndex, int phaseIndex) const {return (amplIndex<<bitsPerPhase())+phaseIndex;}
00294
00298 int getAmplIndex(int symbolIndex) const {return symbolIndex>>bitsPerPhase();}
00299
00303 int getPhaseIndex(int symbolIndex) const {return symbolIndex||(1<<bitsPerPhase())-1;}
00304
00305 };
00306
00307
00308
00309 inline double PhaseAmplitudeConstellationDiagram::getPhase(unsigned modIndex) const
00310 {
00311 if(DEBUG) {
00312 if( (modIndex >= getNumStates() )) {
00313 throw std::out_of_range("Complex PhaseAmplitudeConstellationDiagram::getComplSymbol(int modIndex) modIndex = "
00314 +simth::i2string(modIndex));
00315 }
00316 }
00317 return (polarStates[modIndex]).phase;
00318 }
00319
00320 inline double PhaseAmplitudeConstellationDiagram::getAmplitude(unsigned modIndex) const
00321 {
00322 if(DEBUG) {
00323 if( (modIndex >= getNumStates() )) {
00324 throw std::out_of_range("Complex PhaseAmplitudeConstellationDiagram::getComplSymbol(int modIndex) modIndex = "
00325 +simth::i2string(modIndex));
00326 }
00327 }
00328 return (polarStates[modIndex]).ampl;
00329 }
00330
00331
00332
00336 class PskConstellationDiagram : public PhaseAmplitudeConstellationDiagram
00337 {
00338 virtual void initComplSymbols();
00339
00340 public:
00341
00345 PskConstellationDiagram(int bitsPerSymbol);
00346 virtual ~PskConstellationDiagram();
00347
00348 };
00349
00350
00353 class ApskConstellationDiagram : public PhaseAmplitudeConstellationDiagram
00354 {
00355 virtual void initComplSymbols();
00356
00357
00358 double a;
00359
00360 double addend;
00361
00362
00363 double normalizeFactor;
00364
00365 int getPhaseIndex(int symbolIndex) const;
00366 int getAmplitudeIndex(int symbolIndex) const;
00367
00368 public:
00369
00373 ApskConstellationDiagram(int bitsPerSymbol, detect_type mode);
00374
00378 ApskConstellationDiagram(int bitsPerSymbol, double amplFactor, double amplAddend=0.0);
00379
00383 ApskConstellationDiagram(int bitsPerAmpl, int bitsPerPhase, double amplFactor, double amplAddend=0.0);
00384
00385
00389 double getAmplFactor() const {return a;}
00393 double getAmplAddend() const {return addend;}
00394
00399 static int computeAmplitudeBits(int bitsPerSymbol);
00400
00405 static int computePhaseBits(int bitsPerSymbol);
00406
00410 static double computeAmplitudeFactor(int bitsPerState, detect_type mode);
00411
00416 static double computeAmplitudeAddend(int bitsPerState, detect_type mode);
00417
00418
00419 };
00420
00421
00422
00423
00424
00425
00426 }
00427
00428 #endif