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