diff options
author | Tom Rondeau <trondeau@vt.edu> | 2011-04-08 22:36:16 -0400 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2011-04-08 22:36:16 -0400 |
commit | d543b6847b02371c3e63fcc517333a2e41aed15d (patch) | |
tree | adc0b16995234d1a71a4e07c1ce3a5424437e3ac /gr-digital/lib/digital_constellation.cc | |
parent | c6d7be41abc63a9e5b52a12ef05d578f09797054 (diff) |
gr-digital: formatting constellation block for our style; adding 8PSK constellation.
Diffstat (limited to 'gr-digital/lib/digital_constellation.cc')
-rw-r--r-- | gr-digital/lib/digital_constellation.cc | 204 |
1 files changed, 149 insertions, 55 deletions
diff --git a/gr-digital/lib/digital_constellation.cc b/gr-digital/lib/digital_constellation.cc index 804a65ac86..bfed843206 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; + } } |