1 /* -*- c++ -*- */
2 /*
3  * Copyright 2015 Free Software Foundation, Inc.
4  *
5  * This is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3, or (at your option)
8  * any later version.
9  *
10  * This software is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this software; see the file COPYING.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifndef INCLUDED_DTV_DVBT_VITERBI_DECODER_IMPL_H
22 #define INCLUDED_DTV_DVBT_VITERBI_DECODER_IMPL_H
23 
24 #include "dvbt_configure.h"
25 #include <gnuradio/dtv/dvbt_viterbi_decoder.h>
26 
27 #ifdef DTV_SSE2
28 #include <xmmintrin.h>
29 #endif
30 
31 /* The two generator polynomials for the NASA Standard K=7 code.
32  * Since these polynomials are known to be optimal for this constraint
33  * length there is not much point in changing them.
34  */
35 
36 #define POLYA 0x4f
37 #define POLYB 0x6d
38 // Maximum number of traceback bytes
39 #define TRACEBACK_MAX 24
40 
41 #ifdef DTV_SSE2
42 union branchtab27 {
43     unsigned char c[32];
44     __m128i v[2];
45 };
46 #else
47 struct branchtab27 {
48     unsigned char c[32];
49 };
50 #endif
51 
52 namespace gr {
53 namespace dtv {
54 
55 class dvbt_viterbi_decoder_impl : public dvbt_viterbi_decoder
56 {
57 private:
58     dvbt_configure config;
59 
60     // Puncturing vectors
61     static const unsigned char d_puncture_1_2[];
62     static const unsigned char d_puncture_2_3[];
63     static const unsigned char d_puncture_3_4[];
64     static const unsigned char d_puncture_5_6[];
65     static const unsigned char d_puncture_7_8[];
66     static const unsigned char d_Partab[];
67 
68 #ifdef DTV_SSE2
69     static __m128i d_metric0[4];
70     static __m128i d_metric1[4];
71     static __m128i d_path0[4];
72     static __m128i d_path1[4];
73 #else
74     static unsigned char d_metric0_generic[64];
75     static unsigned char d_metric1_generic[64];
76     static unsigned char d_path0_generic[64];
77     static unsigned char d_path1_generic[64];
78 #endif
79 
80 #ifdef DTV_SSE2
81     static branchtab27 Branchtab27_sse2[2];
82 #else
83     static branchtab27 Branchtab27_generic[2];
84 #endif
85 
86     // Metrics for each state
87     static unsigned char mmresult[64];
88     // Paths for each state
89     static unsigned char ppresult[TRACEBACK_MAX][64];
90 
91     // Current puncturing vector
92     const unsigned char* d_puncture;
93 
94     // Code rate k/n
95     int d_k;
96     int d_n;
97     // Constellation with m
98     int d_m;
99 
100     // Block size
101     int d_bsize;
102     // Symbols to consume on decoding from one block
103     int d_nsymbols;
104     // Number of bits after depuncturing a block
105     int d_nbits;
106     // Number of full packed out bytes
107     int d_nout;
108 
109     // Traceback (in bytes)
110     int d_ntraceback;
111 
112     // Viterbi tables
113     int mettab[2][256];
114 
115     // Buffer to keep the input bits
116     unsigned char* d_inbits;
117 
118     // This is used to get rid of traceback on the first frame
119     int d_init;
120 
121     // Position in circular buffer where the current decoded byte is stored
122     int store_pos;
123 
124 #ifdef DTV_SSE2
125     void dvbt_viterbi_chunks_init_sse2(__m128i* mm0, __m128i* pp0);
126     void dvbt_viterbi_butterfly2_sse2(
127         unsigned char* symbols, __m128i m0[], __m128i m1[], __m128i p0[], __m128i p1[]);
128     unsigned char dvbt_viterbi_get_output_sse2(__m128i* mm0,
129                                                __m128i* pp0,
130                                                int ntraceback,
131                                                unsigned char* outbuf);
132 #else
133     void dvbt_viterbi_chunks_init_generic(unsigned char* mm0, unsigned char* pp0);
134     void dvbt_viterbi_butterfly2_generic(unsigned char* symbols,
135                                          unsigned char m0[],
136                                          unsigned char m1[],
137                                          unsigned char p0[],
138                                          unsigned char p1[]);
139     unsigned char dvbt_viterbi_get_output_generic(unsigned char* mm0,
140                                                   unsigned char* pp0,
141                                                   int ntraceback,
142                                                   unsigned char* outbuf);
143 #endif
144 
145 public:
146     dvbt_viterbi_decoder_impl(dvb_constellation_t constellation,
147                               dvbt_hierarchy_t hierarchy,
148                               dvb_code_rate_t coderate,
149                               int bsize);
150     ~dvbt_viterbi_decoder_impl();
151 
152     void forecast(int noutput_items, gr_vector_int& ninput_items_required);
153 
154     int general_work(int noutput_items,
155                      gr_vector_int& ninput_items,
156                      gr_vector_const_void_star& input_items,
157                      gr_vector_void_star& output_items);
158 };
159 
160 } // namespace dtv
161 } // namespace gr
162 
163 #endif /* INCLUDED_DTV_DVBT_VITERBI_DECODER_IMPL_H */
164