Statistics
| Branch: | Tag: | Revision:

root / gr-digital / lib / digital_mpsk_snr_est_cc.cc @ 6e52e9f8

History | View | Annotate | Download (4.5 kB)

1
/* -*- c++ -*- */
2
/*
3
 * Copyright 2011 Free Software Foundation, Inc.
4
 * 
5
 * This file is part of GNU Radio
6
 * 
7
 * GNU Radio is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3, or (at your option)
10
 * any later version.
11
 * 
12
 * GNU Radio is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU General Public License
18
 * along with GNU Radio; see the file COPYING.  If not, write to
19
 * the Free Software Foundation, Inc., 51 Franklin Street,
20
 * Boston, MA 02110-1301, USA.
21
 */
22
23
#ifdef HAVE_CONFIG_H
24
#include <config.h>
25
#endif
26
27
#include <digital_mpsk_snr_est_cc.h>
28
#include <gr_io_signature.h>
29
#include <cstdio>
30
31
digital_mpsk_snr_est_cc_sptr
32
digital_make_mpsk_snr_est_cc(snr_est_type_t type,
33
                             int tag_nsamples,
34
                             double alpha)
35
{
36
  return gnuradio::get_initial_sptr(new digital_mpsk_snr_est_cc(
37
                                        type, tag_nsamples, alpha));
38
}
39
40
digital_mpsk_snr_est_cc::digital_mpsk_snr_est_cc(snr_est_type_t type,
41
                                                 int tag_nsamples,
42
                                                 double alpha)
43
  : gr_sync_block ("mpsk_snr_est_cc",
44
                   gr_make_io_signature(1, 1, sizeof(gr_complex)),
45
                   gr_make_io_signature(1, 1, sizeof(gr_complex)))
46
{
47
  d_snr_est = NULL;
48
49
  d_type = type;
50
  d_nsamples = tag_nsamples;
51
  d_count = 0;
52
  set_alpha(alpha);
53
54
  set_type(type);
55
56
  // at least 1 estimator has to look back
57
  set_history(2);
58
59
  std::stringstream str;
60
  str << name() << unique_id();
61
  d_me = pmt::pmt_string_to_symbol(str.str());
62
  d_key = pmt::pmt_string_to_symbol("snr");
63
}
64
65
digital_mpsk_snr_est_cc::~digital_mpsk_snr_est_cc()
66
{
67
  if(d_snr_est)
68
    delete d_snr_est;
69
}
70
71
int
72
digital_mpsk_snr_est_cc::work(int noutput_items,
73
                              gr_vector_const_void_star &input_items,
74
                              gr_vector_void_star &output_items)
75
{
76
  // This is a pass-through block; copy input to output
77
  memcpy(output_items[0], input_items[0],
78
         noutput_items * sizeof(gr_complex));
79
80
  const gr_complex *in = (const gr_complex*)input_items[0];
81
  
82
  // Update, calculate, and issue an SNR tag every d_nsamples
83
  int index = 0, x = 0;
84
  int64_t nwritten = nitems_written(0);
85
  while(index + (d_nsamples-d_count) <= noutput_items) {
86
    x = d_nsamples - d_count;
87
    nwritten += x;
88
        
89
    // Update the SNR estimate registers from the current input
90
    d_snr_est->update(x, &in[index]);
91
92
    // Issue a tag with the SNR data
93
    pmt::pmt_t pmt_snr = pmt::pmt_from_double(d_snr_est->snr());
94
    add_item_tag(0,            // stream ID
95
                 nwritten,     // tag's sample number
96
                 d_key,        // snr key
97
                 pmt_snr,      // SNR
98
                 d_me);        // block src id
99
100
    index += x;
101
    d_count = 0;
102
  }
103
  
104
  // Keep track of remaining items and update estimators
105
  x = noutput_items - index;
106
  d_count += x;
107
  d_snr_est->update(x, &in[index]);
108
  
109
  return noutput_items;
110
}
111
112
double
113
digital_mpsk_snr_est_cc::snr()
114
{
115
  if(d_snr_est)
116
    return d_snr_est->snr();
117
  else
118
    throw std::runtime_error("digital_mpsk_snr_est_cc:: No SNR estimator defined.\n");
119
}
120
121
snr_est_type_t
122
digital_mpsk_snr_est_cc::type() const
123
{
124
  return d_type;
125
}
126
127
int
128
digital_mpsk_snr_est_cc::tag_nsample() const
129
{
130
  return d_nsamples;
131
}
132
133
double
134
digital_mpsk_snr_est_cc::alpha() const
135
{
136
  return d_alpha;
137
}
138
139
void
140
digital_mpsk_snr_est_cc::set_type(snr_est_type_t t)
141
{
142
  d_type = t;
143
144
  if(d_snr_est)
145
    delete d_snr_est;
146
147
  switch (d_type) {
148
  case(SNR_EST_SIMPLE):
149
    d_snr_est = new digital_impl_mpsk_snr_est_simple(d_alpha);
150
    break;
151
  case(SNR_EST_SKEW):
152
    d_snr_est = new digital_impl_mpsk_snr_est_skew(d_alpha);
153
    break;
154
  case(SNR_EST_M2M4):
155
    d_snr_est = new digital_impl_mpsk_snr_est_m2m4(d_alpha);
156
    break;
157
  case(SNR_EST_SVR):
158
    d_snr_est = new digital_impl_mpsk_snr_est_svr(d_alpha);
159
    break;
160
  default:
161
    throw std::invalid_argument("digital_mpsk_snr_est_cc: unknown type specified.\n");
162
  }
163
}
164
165
void
166
digital_mpsk_snr_est_cc::set_tag_nsample(int n)
167
{
168
  if(n > 0) {
169
    d_nsamples = n;
170
    d_count = 0;    // reset state
171
  }
172
  else
173
    throw std::invalid_argument("digital_mpsk_snr_est_cc: tag_nsamples can't be <= 0\n");
174
}
175
176
void
177
digital_mpsk_snr_est_cc::set_alpha(double alpha)
178
{
179
  if((alpha >= 0) && (alpha <= 1.0)) {
180
    d_alpha = alpha;
181
    if(d_snr_est)
182
      d_snr_est->set_alpha(d_alpha);
183
  }
184
  else
185
    throw std::invalid_argument("digital_mpsk_snr_est_cc: alpha must be in [0,1]\n");
186
}