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