diff options
author | Tom Rondeau | 2011-04-08 22:36:16 -0400 |
---|---|---|
committer | Tom Rondeau | 2011-04-08 22:36:16 -0400 |
commit | d543b6847b02371c3e63fcc517333a2e41aed15d (patch) | |
tree | adc0b16995234d1a71a4e07c1ce3a5424437e3ac | |
parent | c6d7be41abc63a9e5b52a12ef05d578f09797054 (diff) | |
download | gnuradio-d543b6847b02371c3e63fcc517333a2e41aed15d.tar.gz gnuradio-d543b6847b02371c3e63fcc517333a2e41aed15d.tar.bz2 gnuradio-d543b6847b02371c3e63fcc517333a2e41aed15d.zip |
gr-digital: formatting constellation block for our style; adding 8PSK constellation.
-rw-r--r-- | gr-digital/lib/digital_constellation.cc | 204 | ||||
-rw-r--r-- | gr-digital/lib/digital_constellation.h | 58 |
2 files changed, 193 insertions, 69 deletions
diff --git a/gr-digital/lib/digital_constellation.cc b/gr-digital/lib/digital_constellation.cc index 804a65ac8..bfed84320 100644 --- a/gr-digital/lib/digital_constellation.cc +++ b/gr-digital/lib/digital_constellation.cc @@ -63,19 +63,25 @@ digital_constellation::digital_constellation () : } //! Returns the constellation points for a symbol value -void digital_constellation::map_to_points(unsigned int value, gr_complex *points) { +void +digital_constellation::map_to_points(unsigned int value, gr_complex *points) +{ for (unsigned int i=0; i<d_dimensionality; i++) points[i] = d_constellation[value*d_dimensionality + i]; } -std::vector<gr_complex> digital_constellation::map_to_points_v(unsigned int value) { +std::vector<gr_complex> +digital_constellation::map_to_points_v(unsigned int value) +{ std::vector<gr_complex> points_v; points_v.resize(d_dimensionality); map_to_points(value, &(points_v[0])); return points_v; } -float digital_constellation::get_distance(unsigned int index, const gr_complex *sample) { +float +digital_constellation::get_distance(unsigned int index, const gr_complex *sample) +{ float dist = 0; for (unsigned int i=0; i<d_dimensionality; i++) { dist += norm(sample[i] - d_constellation[index*d_dimensionality + i]); @@ -83,8 +89,9 @@ float digital_constellation::get_distance(unsigned int index, const gr_complex * return dist; } -unsigned int digital_constellation::get_closest_point(const gr_complex *sample) { - +unsigned int +digital_constellation::get_closest_point(const gr_complex *sample) +{ unsigned int min_index = 0; float min_euclid_dist; float euclid_dist; @@ -101,7 +108,8 @@ unsigned int digital_constellation::get_closest_point(const gr_complex *sample) return min_index; } -unsigned int digital_constellation::decision_maker_pe(const gr_complex *sample, float *phase_error) +unsigned int +digital_constellation::decision_maker_pe(const gr_complex *sample, float *phase_error) { unsigned int index = decision_maker(sample); *phase_error = 0; @@ -128,7 +136,9 @@ std::vector<gr_complex> digital_constellation::s_points () { return d_constellation; } -std::vector<std::vector<gr_complex> > digital_constellation::v_points () { +std::vector<std::vector<gr_complex> > +digital_constellation::v_points () +{ std::vector<std::vector<gr_complex> > vv_const; vv_const.resize(d_arity); for (unsigned int p=0; p<d_arity; p++) { @@ -142,7 +152,10 @@ std::vector<std::vector<gr_complex> > digital_constellation::v_points () { return vv_const; } -void digital_constellation::calc_metric(const gr_complex *sample, float *metric, trellis_metric_type_t type) { +void +digital_constellation::calc_metric(const gr_complex *sample, float *metric, + trellis_metric_type_t type) +{ switch (type){ case TRELLIS_EUCLIDEAN: calc_euclidean_metric(sample, metric); @@ -158,13 +171,17 @@ void digital_constellation::calc_metric(const gr_complex *sample, float *metric, } } -void digital_constellation::calc_euclidean_metric(const gr_complex *sample, float *metric) { +void +digital_constellation::calc_euclidean_metric(const gr_complex *sample, float *metric) +{ for (unsigned int o=0; o<d_arity; o++) { metric[o] = get_distance(o, sample); } } -void digital_constellation::calc_hard_symbol_metric(const gr_complex *sample, float *metric){ +void +digital_constellation::calc_hard_symbol_metric(const gr_complex *sample, float *metric) +{ float minm = FLT_MAX; unsigned int minmi = 0; for (unsigned int o=0; o<d_arity; o++) { @@ -179,56 +196,68 @@ void digital_constellation::calc_hard_symbol_metric(const gr_complex *sample, fl } } -void digital_constellation::calc_arity () { +void +digital_constellation::calc_arity () +{ if (d_constellation.size() % d_dimensionality != 0) throw std::runtime_error ("Constellation vector size must be a multiple of the dimensionality."); d_arity = d_constellation.size()/d_dimensionality; } -unsigned int digital_constellation::decision_maker_v (std::vector<gr_complex> sample) { +unsigned int +digital_constellation::decision_maker_v (std::vector<gr_complex> sample) +{ assert(sample.size() == d_dimensionality); return decision_maker (&(sample[0])); } digital_constellation_calcdist_sptr -digital_make_constellation_calcdist(std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code, - unsigned int rotational_symmetry, unsigned int dimensionality) +digital_make_constellation_calcdist(std::vector<gr_complex> constellation, + std::vector<unsigned int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int dimensionality) { - return digital_constellation_calcdist_sptr(new digital_constellation_calcdist (constellation, pre_diff_code, rotational_symmetry, - dimensionality)); + return digital_constellation_calcdist_sptr(new digital_constellation_calcdist + (constellation, pre_diff_code, + rotational_symmetry, dimensionality)); } digital_constellation_calcdist::digital_constellation_calcdist(std::vector<gr_complex> constellation, - std::vector<unsigned int> pre_diff_code, - unsigned int rotational_symmetry, - unsigned int dimensionality) : + std::vector<unsigned int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int dimensionality) : digital_constellation(constellation, pre_diff_code, rotational_symmetry, dimensionality) {} // Chooses points base on shortest distance. // Inefficient. -unsigned int digital_constellation_calcdist::decision_maker(const gr_complex *sample) +unsigned int +digital_constellation_calcdist::decision_maker(const gr_complex *sample) { return get_closest_point(sample); } digital_constellation_sector::digital_constellation_sector (std::vector<gr_complex> constellation, - std::vector<unsigned int> pre_diff_code, - unsigned int rotational_symmetry, - unsigned int dimensionality, - unsigned int n_sectors) : + std::vector<unsigned int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int dimensionality, + unsigned int n_sectors) : digital_constellation(constellation, pre_diff_code, rotational_symmetry, dimensionality), n_sectors(n_sectors) { } -unsigned int digital_constellation_sector::decision_maker (const gr_complex *sample) { +unsigned int +digital_constellation_sector::decision_maker (const gr_complex *sample) +{ unsigned int sector; sector = get_sector(sample); return sector_values[sector]; } -void digital_constellation_sector::find_sector_values () { +void +digital_constellation_sector::find_sector_values () +{ unsigned int i; sector_values.clear(); for (i=0; i<n_sectors; i++) { @@ -238,21 +267,24 @@ void digital_constellation_sector::find_sector_values () { digital_constellation_rect_sptr digital_make_constellation_rect(std::vector<gr_complex> constellation, - std::vector<unsigned int> pre_diff_code, - unsigned int rotational_symmetry, - unsigned int real_sectors, unsigned int imag_sectors, - float width_real_sectors, float width_imag_sectors) -{ - return digital_constellation_rect_sptr(new digital_constellation_rect (constellation, pre_diff_code, rotational_symmetry, - real_sectors, imag_sectors, width_real_sectors, - width_imag_sectors)); + std::vector<unsigned int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int real_sectors, unsigned int imag_sectors, + float width_real_sectors, float width_imag_sectors) +{ + return digital_constellation_rect_sptr(new digital_constellation_rect + (constellation, pre_diff_code, + rotational_symmetry, + real_sectors, imag_sectors, + width_real_sectors, + width_imag_sectors)); } digital_constellation_rect::digital_constellation_rect (std::vector<gr_complex> constellation, - std::vector<unsigned int> pre_diff_code, - unsigned int rotational_symmetry, - unsigned int real_sectors, unsigned int imag_sectors, - float width_real_sectors, float width_imag_sectors) : + std::vector<unsigned int> pre_diff_code, + unsigned int rotational_symmetry, + unsigned int real_sectors, unsigned int imag_sectors, + float width_real_sectors, float width_imag_sectors) : digital_constellation_sector(constellation, pre_diff_code, rotational_symmetry, 1, 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) @@ -260,20 +292,31 @@ digital_constellation_rect::digital_constellation_rect (std::vector<gr_complex> find_sector_values(); } -unsigned int digital_constellation_rect::get_sector (const gr_complex *sample) { +unsigned int +digital_constellation_rect::get_sector (const 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); - if (real_sector < 0) real_sector = 0; - if (real_sector >= n_real_sectors) real_sector = n_real_sectors-1; + if(real_sector < 0) + real_sector = 0; + if(real_sector >= (int)n_real_sectors) + real_sector = n_real_sectors-1; + imag_sector = int(imag(*sample)/d_width_imag_sectors + n_imag_sectors/2.0); - if (imag_sector < 0) imag_sector = 0; - if (imag_sector >= n_imag_sectors) imag_sector = n_imag_sectors-1; + if(imag_sector < 0) + imag_sector = 0; + if(imag_sector >= (int)n_imag_sectors) + imag_sector = n_imag_sectors-1; + sector = real_sector * n_imag_sectors + imag_sector; return sector; } -unsigned int digital_constellation_rect::calc_sector_value (unsigned int sector) { +unsigned int +digital_constellation_rect::calc_sector_value (unsigned int sector) +{ unsigned int real_sector, imag_sector; gr_complex sector_center; unsigned int closest_point; @@ -288,32 +331,38 @@ unsigned int digital_constellation_rect::calc_sector_value (unsigned int sector) digital_constellation_psk_sptr digital_make_constellation_psk(std::vector<gr_complex> constellation, - std::vector<unsigned int> pre_diff_code, - unsigned int n_sectors) + std::vector<unsigned int> pre_diff_code, + unsigned int n_sectors) { - return digital_constellation_psk_sptr(new digital_constellation_psk (constellation, pre_diff_code, - n_sectors)); + return digital_constellation_psk_sptr(new digital_constellation_psk + (constellation, pre_diff_code, + n_sectors)); } digital_constellation_psk::digital_constellation_psk (std::vector<gr_complex> constellation, - std::vector<unsigned int> pre_diff_code, - unsigned int n_sectors) : + std::vector<unsigned int> pre_diff_code, + unsigned int n_sectors) : digital_constellation_sector(constellation, pre_diff_code, constellation.size(), 1, n_sectors) { find_sector_values(); } -unsigned int digital_constellation_psk::get_sector (const gr_complex *sample) { +unsigned int +digital_constellation_psk::get_sector (const 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; + if (sector < 0) + sector += n_sectors; u_sector = sector; return sector; } -unsigned int digital_constellation_psk::calc_sector_value (unsigned int sector) { +unsigned int +digital_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(§or_center); @@ -337,7 +386,8 @@ digital_constellation_bpsk::digital_constellation_bpsk () calc_arity(); } -unsigned int digital_constellation_bpsk::decision_maker(const gr_complex *sample) +unsigned int +digital_constellation_bpsk::decision_maker(const gr_complex *sample) { return (real(*sample) > 0); } @@ -362,9 +412,53 @@ digital_constellation_qpsk::digital_constellation_qpsk () calc_arity(); } -unsigned int digital_constellation_qpsk::decision_maker(const gr_complex *sample) +unsigned int +digital_constellation_qpsk::decision_maker(const gr_complex *sample) +{ + // Real component determines small bit. + // Imag component determines big bit. + return 2*(imag(*sample)>0) + (real(*sample)>0); +} + + +digital_constellation_8psk_sptr +digital_make_constellation_8psk() +{ + return digital_constellation_8psk_sptr(new digital_constellation_8psk ()); +} + +digital_constellation_8psk::digital_constellation_8psk () +{ + float angle = M_PI/8.0; + d_constellation.resize(8); + // Gray-coded + d_constellation[0] = gr_complex(cos( 1*angle), sin( 1*angle)); + d_constellation[1] = gr_complex(cos( 7*angle), sin( 3*angle)); + d_constellation[2] = gr_complex(cos(15*angle), sin(15*angle)); + d_constellation[3] = gr_complex(cos( 9*angle), sin( 9*angle)); + d_constellation[4] = gr_complex(cos( 3*angle), sin( 3*angle)); + d_constellation[5] = gr_complex(cos( 5*angle), sin( 5*angle)); + d_constellation[6] = gr_complex(cos(13*angle), sin(13*angle)); + d_constellation[7] = gr_complex(cos(11*angle), sin(11*angle)); + d_rotational_symmetry = 8; + d_dimensionality = 1; + calc_arity(); +} + +unsigned int +digital_constellation_8psk::decision_maker(const gr_complex *sample) { // Real component determines small bit. // Imag component determines big bit. return 2*(imag(*sample)>0) + (real(*sample)>0); + + unsigned int real, imag; + imag = 2*(sample->imag()<=0); + real = (sample->real()<=0); + if(abs(sample->real()) >= abs(sample->imag())) { + return 0 + imag + real; + } + else { + return 4 + imag + real; + } } diff --git a/gr-digital/lib/digital_constellation.h b/gr-digital/lib/digital_constellation.h index 73cc888f9..9da87a4de 100644 --- a/gr-digital/lib/digital_constellation.h +++ b/gr-digital/lib/digital_constellation.h @@ -30,7 +30,7 @@ #include <gr_metric_type.h> /************************************************************/ -/* digital_constellation */ +/* digital_constellation */ /* */ /* Base class defining interface. */ /************************************************************/ @@ -42,7 +42,7 @@ class digital_constellation : public boost::enable_shared_from_this<digital_cons { public: digital_constellation (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code, - unsigned int rotational_symmetry, unsigned int dimensionality); + unsigned int rotational_symmetry, unsigned int dimensionality); digital_constellation (); //! Returns the constellation points for a symbol value @@ -120,7 +120,7 @@ typedef boost::shared_ptr<digital_constellation_calcdist> digital_constellation_ // public constructor digital_constellation_calcdist_sptr digital_make_constellation_calcdist (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code, - unsigned int rotational_symmetry, unsigned int dimensionality); + unsigned int rotational_symmetry, unsigned int dimensionality); class digital_constellation_calcdist : public digital_constellation @@ -141,7 +141,7 @@ class digital_constellation_calcdist : public digital_constellation }; /************************************************************/ -/* digital_constellation_sector */ +/* digital_constellation_sector */ /* */ /* An abstract class. */ /* Constellation space is divided into sectors. */ @@ -176,7 +176,7 @@ class digital_constellation_sector : public digital_constellation }; /************************************************************/ -/* digital_constellation_rect */ +/* digital_constellation_rect */ /* */ /* Only implemented for 1-(complex)dimensional */ /* constellation. */ @@ -229,7 +229,7 @@ class digital_constellation_rect : public digital_constellation_sector }; /************************************************************/ -/* digital_constellation_psk */ +/* digital_constellation_psk */ /* */ /* Constellation space is divided into pie slices sectors. */ /* Each slice is associated with the nearest constellation */ @@ -243,15 +243,17 @@ typedef boost::shared_ptr<digital_constellation_psk> digital_constellation_psk_s // public constructor digital_constellation_psk_sptr -digital_make_constellation_psk (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code, - unsigned int n_sectors); +digital_make_constellation_psk (std::vector<gr_complex> constellation, + std::vector<unsigned int> pre_diff_code, + unsigned int n_sectors); class digital_constellation_psk : public digital_constellation_sector { public: - digital_constellation_psk (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code, - unsigned int n_sectors); + digital_constellation_psk (std::vector<gr_complex> constellation, + std::vector<unsigned int> pre_diff_code, + unsigned int n_sectors); protected: @@ -262,13 +264,14 @@ class digital_constellation_psk : public digital_constellation_sector private: friend digital_constellation_psk_sptr - digital_make_constellation_psk (std::vector<gr_complex> constellation, std::vector<unsigned int> pre_diff_code, - unsigned int n_sectors); + digital_make_constellation_psk (std::vector<gr_complex> constellation, + std::vector<unsigned int> pre_diff_code, + unsigned int n_sectors); }; /************************************************************/ -/* digital_constellation_bpsk */ +/* digital_constellation_bpsk */ /* */ /* Only works for BPSK. */ /* */ @@ -294,7 +297,7 @@ class digital_constellation_bpsk : public digital_constellation }; /************************************************************/ -/* digital_constellation_qpsk */ +/* digital_constellation_qpsk */ /* */ /* Only works for QPSK. */ /* */ @@ -319,4 +322,31 @@ class digital_constellation_qpsk : public digital_constellation }; + +/************************************************************/ +/* digital_constellation_8psk */ +/* */ +/* Only works for 8PSK. */ +/* */ +/************************************************************/ + +class digital_constellation_8psk; +typedef boost::shared_ptr<digital_constellation_8psk> digital_constellation_8psk_sptr; + +// public constructor +digital_constellation_8psk_sptr +digital_make_constellation_8psk (); + +class digital_constellation_8psk : public digital_constellation +{ + public: + + digital_constellation_8psk (); + unsigned int decision_maker (const gr_complex *sample); + + friend digital_constellation_8psk_sptr + digital_make_constellation_8psk (); + +}; + #endif |