1 /* -*- c++ -*- */
2 /*
3 * Copyright 2004,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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "viterbi_combined_impl.h"
28 #include <gnuradio/io_signature.h>
29 #include <iostream>
30
31 namespace gr {
32 namespace trellis {
33
34 template <class IN_T, class OUT_T>
35 typename viterbi_combined<IN_T, OUT_T>::sptr
make(const fsm & FSM,int K,int S0,int SK,int D,const std::vector<IN_T> & TABLE,digital::trellis_metric_type_t TYPE)36 viterbi_combined<IN_T, OUT_T>::make(const fsm& FSM,
37 int K,
38 int S0,
39 int SK,
40 int D,
41 const std::vector<IN_T>& TABLE,
42 digital::trellis_metric_type_t TYPE)
43 {
44 return gnuradio::get_initial_sptr(
45 new viterbi_combined_impl<IN_T, OUT_T>(FSM, K, S0, SK, D, TABLE, TYPE));
46 }
47
48 template <class IN_T, class OUT_T>
viterbi_combined_impl(const fsm & FSM,int K,int S0,int SK,int D,const std::vector<IN_T> & TABLE,digital::trellis_metric_type_t TYPE)49 viterbi_combined_impl<IN_T, OUT_T>::viterbi_combined_impl(
50 const fsm& FSM,
51 int K,
52 int S0,
53 int SK,
54 int D,
55 const std::vector<IN_T>& TABLE,
56 digital::trellis_metric_type_t TYPE)
57 : block("viterbi_combined<IN_T,OUT_T>",
58 io_signature::make(1, -1, sizeof(IN_T)),
59 io_signature::make(1, -1, sizeof(OUT_T))),
60 d_FSM(FSM),
61 d_K(K),
62 d_S0(S0),
63 d_SK(SK),
64 d_D(D),
65 d_TABLE(TABLE),
66 d_TYPE(TYPE) //,
67 // d_trace(FSM.S()*K)
68 {
69 this->set_relative_rate(1, (uint64_t)d_D);
70 this->set_output_multiple(d_K);
71 }
72
73 template <class IN_T, class OUT_T>
set_K(int K)74 void viterbi_combined_impl<IN_T, OUT_T>::set_K(int K)
75 {
76 gr::thread::scoped_lock guard(this->d_setlock);
77 d_K = K;
78 this->set_output_multiple(d_K);
79 }
80
81 template <class IN_T, class OUT_T>
set_D(int D)82 void viterbi_combined_impl<IN_T, OUT_T>::set_D(int D)
83 {
84 gr::thread::scoped_lock guard(this->d_setlock);
85 d_D = D;
86 this->set_relative_rate(1, (uint64_t)d_D);
87 }
88
89 template <class IN_T, class OUT_T>
set_FSM(const fsm & FSM)90 void viterbi_combined_impl<IN_T, OUT_T>::set_FSM(const fsm& FSM)
91 {
92 gr::thread::scoped_lock guard(this->d_setlock);
93 d_FSM = FSM;
94 }
95
96 template <class IN_T, class OUT_T>
set_S0(int S0)97 void viterbi_combined_impl<IN_T, OUT_T>::set_S0(int S0)
98 {
99 gr::thread::scoped_lock guard(this->d_setlock);
100 d_S0 = S0;
101 }
102
103 template <class IN_T, class OUT_T>
set_SK(int SK)104 void viterbi_combined_impl<IN_T, OUT_T>::set_SK(int SK)
105 {
106 gr::thread::scoped_lock guard(this->d_setlock);
107 d_SK = SK;
108 }
109
110 template <class IN_T, class OUT_T>
set_TYPE(digital::trellis_metric_type_t type)111 void viterbi_combined_impl<IN_T, OUT_T>::set_TYPE(digital::trellis_metric_type_t type)
112 {
113 gr::thread::scoped_lock guard(this->d_setlock);
114 d_TYPE = type;
115 }
116
117 template <class IN_T, class OUT_T>
set_TABLE(const std::vector<IN_T> & table)118 void viterbi_combined_impl<IN_T, OUT_T>::set_TABLE(const std::vector<IN_T>& table)
119 {
120 gr::thread::scoped_lock guard(this->d_setlock);
121 d_TABLE = table;
122 }
123
124 template <class IN_T, class OUT_T>
~viterbi_combined_impl()125 viterbi_combined_impl<IN_T, OUT_T>::~viterbi_combined_impl()
126 {
127 }
128
129 template <class IN_T, class OUT_T>
forecast(int noutput_items,gr_vector_int & ninput_items_required)130 void viterbi_combined_impl<IN_T, OUT_T>::forecast(int noutput_items,
131 gr_vector_int& ninput_items_required)
132 {
133 int input_required = d_D * noutput_items;
134 unsigned ninputs = ninput_items_required.size();
135 for (unsigned int i = 0; i < ninputs; i++) {
136 ninput_items_required[i] = input_required;
137 }
138 }
139
140 template <class IN_T, class OUT_T>
general_work(int noutput_items,gr_vector_int & ninput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)141 int viterbi_combined_impl<IN_T, OUT_T>::general_work(
142 int noutput_items,
143 gr_vector_int& ninput_items,
144 gr_vector_const_void_star& input_items,
145 gr_vector_void_star& output_items)
146 {
147 gr::thread::scoped_lock guard(this->d_setlock);
148 int nstreams = input_items.size();
149 int nblocks = noutput_items / d_K;
150
151 for (int m = 0; m < nstreams; m++) {
152 const IN_T* in = (const IN_T*)input_items[m];
153 OUT_T* out = (OUT_T*)output_items[m];
154
155 for (int n = 0; n < nblocks; n++) {
156 viterbi_algorithm_combined(d_FSM.I(),
157 d_FSM.S(),
158 d_FSM.O(),
159 d_FSM.NS(),
160 d_FSM.OS(),
161 d_FSM.PS(),
162 d_FSM.PI(),
163 d_K,
164 d_S0,
165 d_SK,
166 d_D,
167 d_TABLE,
168 d_TYPE,
169 &(in[n * d_K * d_D]),
170 &(out[n * d_K]));
171 }
172 }
173
174 this->consume_each(d_D * noutput_items);
175 return noutput_items;
176 }
177
178 template class viterbi_combined<std::int16_t, std::uint8_t>;
179 template class viterbi_combined<std::int16_t, std::int16_t>;
180 template class viterbi_combined<std::int16_t, std::int32_t>;
181 template class viterbi_combined<std::int32_t, std::uint8_t>;
182 template class viterbi_combined<std::int32_t, std::int16_t>;
183 template class viterbi_combined<std::int32_t, std::int32_t>;
184 template class viterbi_combined<float, std::uint8_t>;
185 template class viterbi_combined<float, std::int16_t>;
186 template class viterbi_combined<float, std::int32_t>;
187 template class viterbi_combined<gr_complex, std::uint8_t>;
188 template class viterbi_combined<gr_complex, std::int16_t>;
189 template class viterbi_combined<gr_complex, std::int32_t>;
190
191
192 } /* namespace trellis */
193 } /* namespace gr */
194