Houston, we have a trunk.
[debian/gnuradio] / gr-error-correcting-codes / src / lib / gr_syms_to_metrics.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 2, 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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gr_syms_to_metrics.h>
28 #include <gr_io_signature.h>
29 #include <assert.h>
30
31 gr_syms_to_metrics_sptr 
32 gr_make_syms_to_metrics (gr_feval_ff* pdf_fcn_0_bit,
33                          gr_feval_ff* pdf_fcn_1_bit,
34                          int n_samples,
35                          float min_sample,
36                          float max_sample,
37                          int sample_precision)
38 {
39   return gr_syms_to_metrics_sptr
40     (new gr_syms_to_metrics (pdf_fcn_0_bit,
41                              pdf_fcn_1_bit,
42                              n_samples,
43                              min_sample,
44                              max_sample,
45                              sample_precision));
46 }
47
48 /*
49  * dummy functions and variables to get the float(*)(float) function
50  * to work properly with the gr_feval_XX stuff.
51  */
52
53 static gr_feval_ff* l_pdf_fcn_0_bit;
54 static gr_feval_ff* l_pdf_fcn_1_bit;
55
56 static float pdf_fcn_0 (float x)
57 {
58   return (l_pdf_fcn_0_bit->eval (x));
59 }
60
61 static float pdf_fcn_1 (float x)
62 {
63   return (l_pdf_fcn_1_bit->eval (x));
64 }
65
66 gr_syms_to_metrics::gr_syms_to_metrics
67 (gr_feval_ff* pdf_fcn_0_bit,
68  gr_feval_ff* pdf_fcn_1_bit,
69  int n_samples,
70  float min_sample,
71  float max_sample,
72  int sample_precision)
73   : gr_block ("syms_to_metrics",
74               gr_make_io_signature (1, -1, sizeof (float)),
75               gr_make_io_signature (0, 0, 0))
76 {
77   if ((sample_precision < 0) | (sample_precision > 32)) {
78     fprintf (stderr, "gr_syms_to_metrics: sample_precision must be "
79              " between 0 and 32.\n");
80     assert (0);
81   }
82
83   l_pdf_fcn_0_bit = pdf_fcn_0_bit;
84   l_pdf_fcn_1_bit = pdf_fcn_1_bit;
85
86   if (sample_precision == 0) {
87     // float
88     d_out_item_size_bytes = sizeof (float);
89     d_code_metrics = new code_metric_ff (&pdf_fcn_0,
90                                          &pdf_fcn_1,
91                                          n_samples,
92                                          min_sample,
93                                          max_sample);
94   } else if (sample_precision <= 8) {
95     // use char
96     d_out_item_size_bytes = sizeof (char);
97     d_code_metrics = new code_metric_fb (&pdf_fcn_0,
98                                          &pdf_fcn_1,
99                                          n_samples,
100                                          min_sample,
101                                          max_sample,
102                                          sample_precision);
103   } else if (sample_precision <= 16) {
104     // use short
105     d_out_item_size_bytes = sizeof (short);
106     d_code_metrics = new code_metric_fs (&pdf_fcn_0,
107                                          &pdf_fcn_1,
108                                          n_samples,
109                                          min_sample,
110                                          max_sample,
111                                          sample_precision);
112   } else {
113     // use long
114     d_out_item_size_bytes = sizeof (long);
115     d_code_metrics = new code_metric_fl (&pdf_fcn_0,
116                                          &pdf_fcn_1,
117                                          n_samples,
118                                          min_sample,
119                                          max_sample,
120                                          sample_precision);
121   }
122
123   set_output_signature (gr_make_io_signature (1, -1, d_out_item_size_bytes));
124 }
125
126 bool gr_syms_to_metrics::check_topology (int ninputs, int noutputs)
127 {
128   return ((noutputs == (2*ninputs)) ? true : false);
129 }
130
131 void
132 gr_syms_to_metrics::forecast
133 (int noutput_items,
134  gr_vector_int &ninput_items_required)
135 {
136   // always 1:1, for all streams
137   for (size_t n = 0; n < ninput_items_required.size(); n++) {
138     ninput_items_required[n] = noutput_items;
139   }
140 }
141
142 int
143 gr_syms_to_metrics::general_work
144 (int noutput_items,
145  gr_vector_int &ninput_items,
146  gr_vector_const_void_star &input_items,
147  gr_vector_void_star &output_items)
148 {
149   size_t l_n_output_items = noutput_items;
150
151   for (size_t n = 0; n < input_items.size(); n++) {
152     float* t_in_buf = (float*)(&input_items[n]);
153     void* t_out_buf_0_bit = (void*)(&(output_items[2*n]));
154     void* t_out_buf_1_bit = (void*)(&(output_items[(2*n)+1]));
155
156     d_code_metrics->convert (l_n_output_items, t_in_buf,
157                              t_out_buf_0_bit, t_out_buf_1_bit);
158   }
159
160   // consume the number of used input items on all input streams
161
162   consume_each (noutput_items);
163
164   // returns number of items written to each output stream
165
166   return (noutput_items);
167 }