1 /* -*- c++ -*- */
2 /*
3 * Copyright 2004,2009,2010,2012,2018 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
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "add_blk_impl.h"
29 #include <gnuradio/io_signature.h>
30 #include <volk/volk.h>
31
32 namespace gr {
33 namespace blocks {
34
35 template <class T>
make(size_t vlen)36 typename add_blk<T>::sptr add_blk<T>::make(size_t vlen)
37 {
38 return gnuradio::get_initial_sptr(new add_blk_impl<T>(vlen));
39 }
40
41
42 template <>
add_blk_impl(size_t vlen)43 add_blk_impl<float>::add_blk_impl(size_t vlen)
44 : sync_block("add_ff",
45 io_signature::make(1, -1, sizeof(float) * vlen),
46 io_signature::make(1, 1, sizeof(float) * vlen)),
47 d_vlen(vlen)
48 {
49 const int alignment_multiple = volk_get_alignment() / sizeof(float);
50 set_alignment(std::max(1, alignment_multiple));
51 }
52
53 template <>
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)54 int add_blk_impl<float>::work(int noutput_items,
55 gr_vector_const_void_star& input_items,
56 gr_vector_void_star& output_items)
57 {
58 float* out = (float*)output_items[0];
59 int noi = d_vlen * noutput_items;
60
61 memcpy(out, input_items[0], noi * sizeof(float));
62 for (size_t i = 1; i < input_items.size(); i++)
63 volk_32f_x2_add_32f(out, out, (const float*)input_items[i], noi);
64 return noutput_items;
65 }
66
67
68 template <class T>
add_blk_impl(size_t vlen)69 add_blk_impl<T>::add_blk_impl(size_t vlen)
70 : sync_block("add_blk",
71 io_signature::make(1, -1, sizeof(T) * vlen),
72 io_signature::make(1, 1, sizeof(T) * vlen)),
73 d_vlen(vlen)
74 {
75 }
76
77 template <class T>
work(int noutput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)78 int add_blk_impl<T>::work(int noutput_items,
79 gr_vector_const_void_star& input_items,
80 gr_vector_void_star& output_items)
81 {
82 T* optr = (T*)output_items[0];
83
84 int ninputs = input_items.size();
85
86 for (size_t i = 0; i < noutput_items * d_vlen; i++) {
87 T acc = ((T*)input_items[0])[i];
88 for (int j = 1; j < ninputs; j++)
89 acc += ((T*)input_items[j])[i];
90
91 *optr++ = (T)acc;
92 }
93
94 return noutput_items;
95 }
96
97 template class add_blk<std::int16_t>;
98 template class add_blk<std::int32_t>;
99 template class add_blk<gr_complex>;
100 template class add_blk<float>;
101 } /* namespace blocks */
102 } /* namespace gr */
103