1 /* -*- c++ -*- */
2 /*
3  * Copyright 2010,2013 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 "annotator_1to1_impl.h"
28 #include <gnuradio/io_signature.h>
29 #include <string.h>
30 #include <iomanip>
31 #include <iostream>
32 
33 namespace gr {
34 namespace blocks {
35 
make(int when,size_t sizeof_stream_item)36 annotator_1to1::sptr annotator_1to1::make(int when, size_t sizeof_stream_item)
37 {
38     return gnuradio::get_initial_sptr(new annotator_1to1_impl(when, sizeof_stream_item));
39 }
40 
annotator_1to1_impl(int when,size_t sizeof_stream_item)41 annotator_1to1_impl::annotator_1to1_impl(int when, size_t sizeof_stream_item)
42     : sync_block("annotator_1to1",
43                  io_signature::make(1, -1, sizeof_stream_item),
44                  io_signature::make(1, -1, sizeof_stream_item)),
45       d_when((uint64_t)when)
46 {
47     set_tag_propagation_policy(TPP_ONE_TO_ONE);
48 
49     d_tag_counter = 0;
50     set_relative_rate(1, 1);
51 }
52 
~annotator_1to1_impl()53 annotator_1to1_impl::~annotator_1to1_impl() {}
54 
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)55 int annotator_1to1_impl::work(int noutput_items,
56                               gr_vector_const_void_star& input_items,
57                               gr_vector_void_star& output_items)
58 {
59     const float* in = (const float*)input_items[0];
60     float* out = (float*)output_items[0];
61 
62     std::stringstream str;
63     str << name() << unique_id();
64 
65     uint64_t abs_N = 0;
66     int ninputs = input_items.size();
67     for (int i = 0; i < ninputs; i++) {
68         abs_N = nitems_read(i);
69 
70         std::vector<tag_t> all_tags;
71         get_tags_in_range(all_tags, i, abs_N, abs_N + noutput_items);
72 
73         std::vector<tag_t>::iterator itr;
74         for (itr = all_tags.begin(); itr != all_tags.end(); itr++) {
75             d_stored_tags.push_back(*itr);
76         }
77     }
78 
79     // Storing the current noutput_items as the value to the "noutput_items" key
80     pmt::pmt_t srcid = pmt::string_to_symbol(str.str());
81     pmt::pmt_t key = pmt::string_to_symbol("seq");
82 
83     // Work does nothing to the data stream; just copy all inputs to outputs
84     // Adds a new tag when the number of items read is a multiple of d_when
85     abs_N = nitems_read(0);
86     int noutputs = output_items.size();
87     for (int j = 0; j < noutput_items; j++) {
88         // the min() is a hack to make sure this doesn't segfault if
89         // there are a different number of ins and outs. This is
90         // specifically designed to test the 1-to-1 propagation policy.
91         for (int i = 0; i < std::min(noutputs, ninputs); i++) {
92             if (abs_N % d_when == 0) {
93                 pmt::pmt_t value = pmt::from_uint64(d_tag_counter++);
94                 add_item_tag(i, abs_N, key, value, srcid);
95             }
96 
97             in = (const float*)input_items[i];
98             out = (float*)output_items[i];
99             out[j] = in[j];
100         }
101         abs_N++;
102     }
103 
104     return noutput_items;
105 }
106 
107 } /* namespace blocks */
108 } /* namespace gr */
109