GNU Radio Manual and C++ API Reference  3.7.4
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
volk_8u_conv_k7_r2puppet_8u.h
Go to the documentation of this file.
1 #ifndef INCLUDED_volk_8u_conv_k7_r2puppet_8u_H
2 #define INCLUDED_volk_8u_conv_k7_r2puppet_8u_H
3 
4 #include <volk/volk.h>
6 
7 typedef union {
8  //decision_t is a BIT vector
9  unsigned char* t;
10  unsigned int* w;
11 } p_decision_t;
12 
13 static inline int parity(int x, unsigned char* Partab)
14 {
15  x ^= (x >> 16);
16  x ^= (x >> 8);
17  return Partab[x];
18 }
19 
20 static inline int chainback_viterbi(unsigned char* data,
21  unsigned int nbits,
22  unsigned int endstate,
23  unsigned int tailsize,
24  unsigned char* decisions)
25 {
26  unsigned char* d;
27  int d_ADDSHIFT = 0;
28  int d_numstates = (1 << 6);
29  int d_decision_t_size = d_numstates/8;
30  unsigned int d_k = 7;
31  int d_framebits = nbits;
32  /* ADDSHIFT and SUBSHIFT make sure that the thing returned is a byte. */
33  d = decisions;
34  /* Make room beyond the end of the encoder register so we can
35  * accumulate a full byte of decoded data
36  */
37 
38  endstate = (endstate%d_numstates) << d_ADDSHIFT;
39 
40  /* The store into data[] only needs to be done every 8 bits.
41  * But this avoids a conditional branch, and the writes will
42  * combine in the cache anyway
43  */
44 
45  d += tailsize * d_decision_t_size ; /* Look past tail */
46  int retval;
47  int dif = tailsize - (d_k - 1);
48  //printf("break, %d, %d\n", dif, (nbits+dif)%d_framebits);
49  p_decision_t dec;
50  while(nbits-- > d_framebits - (d_k - 1)) {
51  int k;
52  dec.t = &d[nbits * d_decision_t_size];
53  k = (dec.w[(endstate>>d_ADDSHIFT)/32] >> ((endstate>>d_ADDSHIFT)%32)) & 1;
54 
55  endstate = (endstate >> 1) | (k << (d_k-2+d_ADDSHIFT));
56  //data[((nbits+dif)%nbits)>>3] = endstate>>d_SUBSHIFT;
57  //printf("%d, %d\n", k, (nbits+dif)%d_framebits);
58  data[((nbits+dif)%d_framebits)] = k;
59 
60  retval = endstate;
61  }
62  nbits += 1;
63 
64  while(nbits-- != 0) {
65  int k;
66 
67  dec.t = &d[nbits * d_decision_t_size];
68 
69  k = (dec.w[(endstate>>d_ADDSHIFT)/32] >> ((endstate>>d_ADDSHIFT)%32)) & 1;
70 
71  endstate = (endstate >> 1) | (k << (d_k-2+d_ADDSHIFT));
72  data[((nbits+dif)%d_framebits)] = k;
73  }
74  //printf("%d, %d, %d, %d, %d, %d, %d, %d\n", data[4095],data[4094],data[4093],data[4092],data[4091],data[4090],data[4089],data[4088]);
75 
76 
77  return retval >> d_ADDSHIFT;
78 }
79 
80 
81 #if LV_HAVE_SSE3
82 
83 #include <pmmintrin.h>
84 #include <emmintrin.h>
85 #include <xmmintrin.h>
86 #include <mmintrin.h>
87 #include <stdio.h>
88 
89 
90 
91 
92 
93 static inline void volk_8u_conv_k7_r2puppet_8u_spiral(unsigned char* syms, unsigned char* dec, unsigned int framebits) {
94 
95 
96  static int once = 1;
97  int d_numstates = (1 << 6);
98  int rate = 2;
99  static unsigned char* D;
100  static unsigned char* Y;
101  static unsigned char* X;
102  static unsigned int excess = 6;
103  static unsigned char* Branchtab;
104  static unsigned char Partab[256];
105 
106  int d_polys[2] = {79, 109};
107 
108 
109  if(once) {
110 
111  X = (unsigned char*)volk_malloc(2*d_numstates, volk_get_alignment());
112  Y = X + d_numstates;
113  Branchtab = (unsigned char*)volk_malloc(d_numstates/2*rate, volk_get_alignment());
114  D = (unsigned char*)volk_malloc((d_numstates/8) * (framebits + 6), volk_get_alignment());
115  int state, i;
116  int cnt,ti;
117 
118  /* Initialize parity lookup table */
119  for(i=0;i<256;i++){
120  cnt = 0;
121  ti = i;
122  while(ti){
123  if(ti & 1)
124  cnt++;
125  ti >>= 1;
126  }
127  Partab[i] = cnt & 1;
128  }
129  /* Initialize the branch table */
130  for(state=0;state < d_numstates/2;state++){
131  for(i=0; i<rate; i++){
132  Branchtab[i*d_numstates/2+state] = (d_polys[i] < 0) ^ parity((2*state) & abs(d_polys[i]), Partab) ? 255 : 0;
133  }
134  }
135 
136  once = 0;
137  }
138 
139  //unbias the old_metrics
140  memset(X, 31, d_numstates);
141 
142  volk_8u_x4_conv_k7_r2_8u_spiral(Y, X, syms, D, framebits/2 - excess, excess, Branchtab);
143 
144  unsigned int min = X[0];
145  int i = 0, state = 0;
146  for(i = 0; i < (d_numstates); ++i) {
147  if(X[i] < min) {
148  min = X[i];
149  state = i;
150  }
151  }
152 
153  chainback_viterbi(dec, framebits/2 -excess, state, excess, D);
154 
155  return;
156 }
157 
158 #endif /*LV_HAVE_SSE3*/
159 
160 
161 
162 
163 
164 #if LV_HAVE_GENERIC
165 
166 
167 static inline void volk_8u_conv_k7_r2puppet_8u_generic(unsigned char* syms, unsigned char* dec, unsigned int framebits) {
168 
169 
170 
171  static int once = 1;
172  int d_numstates = (1 << 6);
173  int rate = 2;
174  static unsigned char* Y;
175  static unsigned char* X;
176  static unsigned char* D;
177  static unsigned int excess = 6;
178  static unsigned char* Branchtab;
179  static unsigned char Partab[256];
180 
181  int d_polys[2] = {79, 109};
182 
183 
184  if(once) {
185 
186  X = (unsigned char*)volk_malloc(2*d_numstates, volk_get_alignment());
187  Y = X + d_numstates;
188  Branchtab = (unsigned char*)volk_malloc(d_numstates/2*rate, volk_get_alignment());
189  D = (unsigned char*)volk_malloc((d_numstates/8) * (framebits + 6), volk_get_alignment());
190 
191  int state, i;
192  int cnt,ti;
193 
194  /* Initialize parity lookup table */
195  for(i=0;i<256;i++){
196  cnt = 0;
197  ti = i;
198  while(ti){
199  if(ti & 1)
200  cnt++;
201  ti >>= 1;
202  }
203  Partab[i] = cnt & 1;
204  }
205  /* Initialize the branch table */
206  for(state=0;state < d_numstates/2;state++){
207  for(i=0; i<rate; i++){
208  Branchtab[i*d_numstates/2+state] = (d_polys[i] < 0) ^ parity((2*state) & abs(d_polys[i]), Partab) ? 255 : 0;
209  }
210  }
211 
212  once = 0;
213  }
214 
215 
216 
217 
218  //unbias the old_metrics
219  memset(X, 31, d_numstates);
220 
221  volk_8u_x4_conv_k7_r2_8u_generic(Y, X, syms, D, framebits/2 - excess, excess, Branchtab);
222 
223  unsigned int min = X[0];
224  int i = 0, state = 0;
225  for(i = 0; i < (d_numstates); ++i) {
226  if(X[i] < min) {
227  min = X[i];
228  state = i;
229  }
230  }
231 
232  chainback_viterbi(dec, framebits/2 -excess, state, excess, D);
233 
234  return;
235 
236 
237 }
238 
239 #endif /* LV_HAVE_GENERIC */
240 
241 #endif /*INCLUDED_volk_8u_conv_k7_r2puppet_8u_H*/
unsigned char * t
Definition: volk_8u_conv_k7_r2puppet_8u.h:9
float min(float a, float b)
Definition: volk_8u_conv_k7_r2puppet_8u.h:7
static int chainback_viterbi(unsigned char *data, unsigned int nbits, unsigned int endstate, unsigned int tailsize, unsigned char *decisions)
Definition: volk_8u_conv_k7_r2puppet_8u.h:20
VOLK_API size_t volk_get_alignment(void)
Get the machine alignment in bytes.
__VOLK_DECL_BEGIN VOLK_API void * volk_malloc(size_t size, size_t alignment)
Allocate size bytes of data aligned to alignment.
static int parity(int x, unsigned char *Partab)
Definition: volk_8u_conv_k7_r2puppet_8u.h:13
unsigned int * w
Definition: volk_8u_conv_k7_r2puppet_8u.h:10