summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation.cc96
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation.h115
-rw-r--r--gnuradio-core/src/lib/general/gr_constellation.i42
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;
+};