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