diff options
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r-- | gnuradio-core/src/lib/general/gr_constellation.cc | 96 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_constellation.h | 115 | ||||
-rw-r--r-- | gnuradio-core/src/lib/general/gr_constellation.i | 42 |
3 files changed, 203 insertions, 50 deletions
diff --git a/gnuradio-core/src/lib/general/gr_constellation.cc b/gnuradio-core/src/lib/general/gr_constellation.cc index 03589dee8..8b98a5731 100644 --- a/gnuradio-core/src/lib/general/gr_constellation.cc +++ b/gnuradio-core/src/lib/general/gr_constellation.cc @@ -24,20 +24,25 @@ #include <gr_constellation.h> #include <gr_math.h> #include <gr_complex.h> +#include <math.h> +#include <iostream> +#include <stdlib.h> + +#define M_TWOPI (2*M_PI) gr_constellation_sptr gr_make_constellation(std::vector<gr_complex> constellation) { return gr_constellation_sptr(new gr_constellation (constellation)); - } +} // Base Constellation Class -gr_constellation::gr_constellation (std::vector<gr_complex> constellation) { - d_constellation = constellation; +gr_constellation::gr_constellation (std::vector<gr_complex> constellation) : + d_constellation(constellation) +{ } - unsigned int get_closest_point(std::vector<gr_complex> constellation, gr_complex sample) { unsigned int table_size = constellation.size(); @@ -66,23 +71,11 @@ unsigned int gr_constellation::decision_maker(gr_complex sample) return min_index; } -gr_constellation_sector_sptr -gr_make_constellation_sector(std::vector<gr_complex> constellation, - unsigned int real_sectors, unsigned int imag_sectors, - float width_real_sectors, float width_imag_sectors) -{ - return gr_constellation_sector_sptr(new gr_constellation_sector (constellation, real_sectors, imag_sectors, width_real_sectors, width_imag_sectors)); - } - gr_constellation_sector::gr_constellation_sector (std::vector<gr_complex> constellation, - unsigned int real_sectors, unsigned int imag_sectors, - float width_real_sectors, float width_imag_sectors) : + unsigned int n_sectors) : gr_constellation(constellation), - n_sectors(real_sectors * imag_sectors), - n_real_sectors(real_sectors), n_imag_sectors(imag_sectors), - d_width_real_sectors(width_real_sectors), d_width_imag_sectors(width_imag_sectors) + n_sectors(n_sectors) { - find_sector_values(); } unsigned int gr_constellation_sector::decision_maker (gr_complex sample) { @@ -91,7 +84,33 @@ unsigned int gr_constellation_sector::decision_maker (gr_complex sample) { return sector_values[sector]; } -unsigned int gr_constellation_sector::get_sector (gr_complex sample) { +void gr_constellation_sector::find_sector_values () { + unsigned int i; + sector_values.clear(); + for (i=0; i<n_sectors; i++) { + sector_values.push_back(calc_sector_value(i)); + } +} + +gr_constellation_rect_sptr +gr_make_constellation_rect(std::vector<gr_complex> constellation, + unsigned int real_sectors, unsigned int imag_sectors, + float width_real_sectors, float width_imag_sectors) +{ + return gr_constellation_rect_sptr(new gr_constellation_rect (constellation, real_sectors, imag_sectors, width_real_sectors, width_imag_sectors)); + } + +gr_constellation_rect::gr_constellation_rect (std::vector<gr_complex> constellation, + unsigned int real_sectors, unsigned int imag_sectors, + float width_real_sectors, float width_imag_sectors) : + gr_constellation_sector(constellation, real_sectors * imag_sectors), + n_real_sectors(real_sectors), n_imag_sectors(imag_sectors), + d_width_real_sectors(width_real_sectors), d_width_imag_sectors(width_imag_sectors) +{ + find_sector_values(); +} + +unsigned int gr_constellation_rect::get_sector (gr_complex sample) { int real_sector, imag_sector; unsigned int sector; real_sector = int(real(sample)/d_width_real_sectors + n_real_sectors/2.0); @@ -104,7 +123,7 @@ unsigned int gr_constellation_sector::get_sector (gr_complex sample) { return sector; } -unsigned int gr_constellation_sector::calc_sector_value (unsigned int sector) { +unsigned int gr_constellation_rect::calc_sector_value (unsigned int sector) { unsigned int real_sector, imag_sector; gr_complex sector_center; unsigned int closest_point; @@ -117,11 +136,36 @@ unsigned int gr_constellation_sector::calc_sector_value (unsigned int sector) { } -void gr_constellation_sector::find_sector_values () { - unsigned int i; - sector_values.clear(); - for (i=0; i<n_sectors; i++) { - sector_values.push_back(calc_sector_value(i)); - } +gr_constellation_psk_sptr +gr_make_constellation_psk(std::vector<gr_complex> constellation, unsigned int n_sectors) +{ + return gr_constellation_psk_sptr(new gr_constellation_psk (constellation, n_sectors)); } +gr_constellation_psk::gr_constellation_psk (std::vector<gr_complex> constellation, + unsigned int n_sectors) : + gr_constellation_sector(constellation, n_sectors) +{ + find_sector_values(); +} + +unsigned int gr_constellation_psk::get_sector (gr_complex sample) { + float phase = arg(sample); + float width = M_TWOPI / n_sectors; + int sector = floor(phase/width + 0.5); + unsigned int u_sector; + if (sector < 0) sector += n_sectors; + u_sector = sector; + // std::cout << phase << " " << width << " " << sector << std::endl; + return sector; +} + +unsigned int gr_constellation_psk::calc_sector_value (unsigned int sector) { + float phase = sector * M_TWOPI / n_sectors; + gr_complex sector_center = gr_complex(cos(phase), sin(phase)); + unsigned int closest_point = get_closest_point(d_constellation, sector_center); + // std::cout << phase << " " << sector_center << " " << closest_point << std::endl; + return closest_point; +} + + diff --git a/gnuradio-core/src/lib/general/gr_constellation.h b/gnuradio-core/src/lib/general/gr_constellation.h index 92ae3c5e2..d7f7b09b4 100644 --- a/gnuradio-core/src/lib/general/gr_constellation.h +++ b/gnuradio-core/src/lib/general/gr_constellation.h @@ -28,6 +28,12 @@ #include <gr_complex.h> #include <boost/enable_shared_from_this.hpp> +/************************************************************/ +/* gr_constellation */ +/* */ +/* Decision maker uses nearest-point method. */ +/************************************************************/ + class gr_constellation; typedef boost::shared_ptr<gr_constellation> gr_constellation_sptr; @@ -36,6 +42,7 @@ gr_constellation_sptr gr_make_constellation (std::vector<gr_complex> constellation); class gr_constellation : public boost::enable_shared_from_this<gr_constellation> +//class gr_constellation { public: @@ -53,6 +60,7 @@ class gr_constellation : public boost::enable_shared_from_this<gr_constellation> } gr_constellation_sptr base() { + //return gr_constellation_sptr(this); return shared_from_this(); } @@ -65,44 +73,119 @@ class gr_constellation : public boost::enable_shared_from_this<gr_constellation> gr_make_constellation (std::vector<gr_complex> constellation); }; -class gr_constellation_sector; -typedef boost::shared_ptr<gr_constellation_sector> gr_constellation_sector_sptr; - -// public constructor -gr_constellation_sector_sptr -gr_make_constellation_sector (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, - float width_real_sectors, float width_imag_sectors); +/************************************************************/ +/* gr_constellation_sector */ +/* */ +/* An abstract class. */ +/* Constellation space is divided into sectors. */ +/* Each sector is associated with the nearest constellation */ +/* point. */ +/************************************************************/ class gr_constellation_sector : public gr_constellation { public: - gr_constellation_sector (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, - float width_real_sectors, float width_imag_sectors); + gr_constellation_sector (std::vector<gr_complex> constellation, + unsigned int n_sectors); unsigned int decision_maker (gr_complex sample); - protected: + // protected: - virtual unsigned int get_sector (gr_complex sample); + virtual unsigned int get_sector (gr_complex sample) = 0; - virtual unsigned int calc_sector_value (unsigned int sector); + virtual unsigned int calc_sector_value (unsigned int sector) = 0; void find_sector_values (); - private: + unsigned int n_sectors; + + // private: std::vector<unsigned int> sector_values; - unsigned int n_sectors; + +}; + +/************************************************************/ +/* gr_constellation_rect */ +/* */ +/* Constellation space is divided into rectangular sectors. */ +/* Each sector is associated with the nearest constellation */ +/* point. */ +/* Works well for square QAM. */ +/* Works for any generic constellation provided sectors are */ +/* not too large. */ +/************************************************************/ + +class gr_constellation_rect; +typedef boost::shared_ptr<gr_constellation_rect> gr_constellation_rect_sptr; + +// public constructor +gr_constellation_rect_sptr +gr_make_constellation_rect (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, + float width_real_sectors, float width_imag_sectors); + +class gr_constellation_rect : public gr_constellation_sector +{ + public: + + gr_constellation_rect (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, + float width_real_sectors, float width_imag_sectors); + + // protected: + + unsigned int get_sector (gr_complex sample); + + unsigned int calc_sector_value (unsigned int sector); + + // private: + unsigned int n_real_sectors; unsigned int n_imag_sectors; float d_width_real_sectors; float d_width_imag_sectors; - friend gr_constellation_sector_sptr - gr_make_constellation_sector (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, + friend gr_constellation_rect_sptr + gr_make_constellation_rect (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, float width_real_sectors, float width_imag_sectors); }; +/************************************************************/ +/* gr_constellation_psk */ +/* */ +/* Constellation space is divided into pie slices sectors. */ +/* Each slice is associated with the nearest constellation */ +/* point. */ +/* Works well for PSK but nothing else. */ +/* Assumes that there is a constellation point at 1. */ +/************************************************************/ + +class gr_constellation_psk; +typedef boost::shared_ptr<gr_constellation_psk> gr_constellation_psk_sptr; + +// public constructor +gr_constellation_psk_sptr +gr_make_constellation_psk (std::vector<gr_complex> constellation, unsigned int n_sectors); + +class gr_constellation_psk : public gr_constellation_sector +{ + public: + + gr_constellation_psk (std::vector<gr_complex> constellation, unsigned int n_sectors); + + // protected: + + unsigned int get_sector (gr_complex sample); + + unsigned int calc_sector_value (unsigned int sector); + + // private: + + friend gr_constellation_psk_sptr + gr_make_constellation_psk (std::vector<gr_complex> constellation, unsigned int n_sectors); + +}; + #endif diff --git a/gnuradio-core/src/lib/general/gr_constellation.i b/gnuradio-core/src/lib/general/gr_constellation.i index bdc5436f2..2d15b8b1e 100644 --- a/gnuradio-core/src/lib/general/gr_constellation.i +++ b/gnuradio-core/src/lib/general/gr_constellation.i @@ -40,19 +40,19 @@ public: gr_constellation_sptr base (); }; -class gr_constellation_sector; -typedef boost::shared_ptr<gr_constellation_sector> gr_constellation_sector_sptr; -%template(gr_constellation_sector_sptr) boost::shared_ptr<gr_constellation_sector>; -%rename(constellation_sector) gr_make_constellation_sector; -gr_constellation_sector_sptr gr_make_constellation_sector(std::vector<gr_complex> constellation_sector, +class gr_constellation_rect; +typedef boost::shared_ptr<gr_constellation_rect> gr_constellation_rect_sptr; +%template(gr_constellation_rect_sptr) boost::shared_ptr<gr_constellation_rect>; +%rename(constellation_rect) gr_make_constellation_rect; +gr_constellation_rect_sptr gr_make_constellation_rect(std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, float width_real_sectors, float width_imag_sectors); -%ignore gr_constellation_sector; +%ignore gr_constellation_rect; -class gr_constellation_sector : public gr_constellation +class gr_constellation_rect : public gr_constellation_sector { public: - gr_constellation_sector (std::vector<gr_complex> constellation, + gr_constellation_rect (std::vector<gr_complex> constellation, unsigned int real_sectors, unsigned int imag_sectors, float width_real_sectors, float width_imag_sectors); std::vector<gr_complex> points (); @@ -60,3 +60,29 @@ public: unsigned int bits_per_symbol (); gr_constellation_sptr base (); }; + +class gr_constellation_psk; +typedef boost::shared_ptr<gr_constellation_psk> gr_constellation_psk_sptr; +%template(gr_constellation_psk_sptr) boost::shared_ptr<gr_constellation_psk>; +%rename(constellation_psk) gr_make_constellation_psk; +gr_constellation_psk_sptr gr_make_constellation_psk(std::vector<gr_complex> constellation, + unsigned int n_sectors); +%ignore gr_constellation_psk; + +class gr_constellation_psk : public gr_constellation_sector +{ +public: + gr_constellation_psk (std::vector<gr_complex> constellation, + unsigned int n_sectors); + std::vector<gr_complex> points (); + unsigned int decision_maker (gr_complex sample); + unsigned int bits_per_symbol (); + + gr_constellation_sptr base (); + + unsigned int get_sector (gr_complex sample); + unsigned int calc_sector_value (unsigned int sector); + void find_sector_values (); + unsigned int n_sectors; + std::vector<unsigned int> sector_values; +}; |