Updated license from GPL version 2 or later to GPL version 3 or later.
[debian/gnuradio] / gnuradio-core / src / lib / general / gr_bin_statistics_f.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006 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 <gr_bin_statistics_f.h>
28 #include <gr_io_signature.h>
29
30 gr_bin_statistics_f_sptr
31 gr_make_bin_statistics_f(unsigned int vlen,
32                         gr_msg_queue_sptr msgq,
33                         gr_feval_dd *tune,
34                         size_t tune_delay,
35                         size_t dwell_delay)
36 {
37   return gr_bin_statistics_f_sptr(new gr_bin_statistics_f(vlen,
38                                                           msgq,
39                                                           tune,
40                                                           tune_delay,
41                                                           dwell_delay));
42 }
43
44 gr_bin_statistics_f::gr_bin_statistics_f(unsigned int vlen,
45                                          gr_msg_queue_sptr msgq,
46                                          gr_feval_dd *tune,
47                                          size_t tune_delay,
48                                          size_t dwell_delay)
49   : gr_sync_block("bin_statistics_f",
50                   gr_make_io_signature(1, 1, sizeof(float) * vlen),
51                   gr_make_io_signature(0, 0, 0)),
52     d_vlen(vlen), d_msgq(msgq), d_tune(tune),
53     d_tune_delay(tune_delay), d_dwell_delay(dwell_delay),
54     d_center_freq(0), d_delay(0),
55     d_max(vlen)
56 {
57   enter_init();
58 }
59
60 gr_bin_statistics_f::~gr_bin_statistics_f()
61 {
62   // NOP
63 }
64
65 void
66 gr_bin_statistics_f::enter_init()
67 {
68   d_state = ST_INIT;
69   d_delay = 0;
70 }
71
72 void
73 gr_bin_statistics_f::enter_tune_delay()
74 {
75   d_state = ST_TUNE_DELAY;
76   d_delay = d_tune_delay;
77   d_center_freq = d_tune->calleval(0);
78 }
79
80 void
81 gr_bin_statistics_f::enter_dwell_delay()
82 {
83   d_state = ST_DWELL_DELAY;
84   d_delay = d_dwell_delay;
85   reset_stats();
86 }
87
88 void
89 gr_bin_statistics_f::leave_dwell_delay()
90 {
91   send_stats();
92 }
93
94 int
95 gr_bin_statistics_f::work(int noutput_items,
96                           gr_vector_const_void_star &input_items,
97                           gr_vector_void_star &output_items)
98 {
99   const float *input = (const float *) input_items[0];
100   size_t vlen = d_max.size();
101
102   int n = 0;
103   int t;
104
105   while (n < noutput_items){
106     switch (d_state){
107
108     case ST_INIT:
109       enter_tune_delay();
110       break;
111
112     case ST_TUNE_DELAY:
113       t = std::min(noutput_items - n, int(d_delay));
114       n += t;
115       d_delay -= t;
116       assert(d_delay >= 0);
117       if (d_delay == 0)
118         enter_dwell_delay();
119       break;
120       
121     case ST_DWELL_DELAY:
122       t = std::min(noutput_items - n, int(d_delay));
123       for (int i = 0; i < t; i++){
124         accrue_stats(&input[n * vlen]);
125         n++;
126       }
127       d_delay -= t;
128       assert(d_delay >= 0);
129       if (d_delay == 0){
130         leave_dwell_delay();
131         enter_tune_delay();
132       }
133       break;
134
135     default:
136       assert(0);
137     }
138   }
139
140   return noutput_items;
141 }
142
143 //////////////////////////////////////////////////////////////////////////
144 //           virtual methods for gathering stats
145 //////////////////////////////////////////////////////////////////////////
146
147 void
148 gr_bin_statistics_f::reset_stats()
149 {
150   for (size_t i = 0; i < vlen(); i++){
151     d_max[i] = 0;
152   }
153 }
154
155 void
156 gr_bin_statistics_f::accrue_stats(const float *input)
157 {
158   for (size_t i = 0; i < vlen(); i++){
159     d_max[i] = std::max(d_max[i], input[i]);    // compute per bin maxima
160   }
161 }
162
163 void
164 gr_bin_statistics_f::send_stats()
165 {
166   if (msgq()->full_p())         // if the queue is full, don't block, drop the data...
167     return;
168
169   // build & send a message
170   gr_message_sptr msg = gr_make_message(0, center_freq(), vlen(), vlen() * sizeof(float));
171   memcpy(msg->msg(), &d_max[0], vlen() * sizeof(float));
172   msgq()->insert_tail(msg);
173 }