GNU Radio's DSD Package
descramble.h
Go to the documentation of this file.
1 /* descramble.h */
2 
3 // Functions for processing the radio-header:
4 // descramble
5 // deinterleave
6 // FECdecoder
7 
8 // (C) 2011 Jonathan Naylor G4KLX
9 
10 /*
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; version 2 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  */
20 
21 // This code was originally written by JOnathan Naylor, G4KLX, as part
22 // of the "pcrepeatercontroller" project
23 // More info:
24 // http://groups.yahoo.com/group/pcrepeatercontroller
25 
26 
27 
28 // Changes:
29 // Convert C++ to C
30 
31 // Version 20111106: initial release
32 
33 
34 
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 // function traceBack
40 int traceBack (int * out, int * m_pathMemory0, int * m_pathMemory1, int * m_pathMemory2, int * m_pathMemory3) {
41  enum FEC_STATE { S0, S1, S2, S3 } state;
42  int loop;
43  int length=0;
44 
45  state=S0;
46 
47  for (loop=329; loop >= 0; loop--, length++) {
48 
49  switch (state) {
50  case S0: // if state S0
51  if (m_pathMemory0[loop]) {
52  state = S2; // lower path
53  } else {
54  state = S0; // upper path
55  }; // end else - if
56  out[loop]=0;
57  break;
58 
59  case S1: // if state S1
60  if (m_pathMemory1[loop]) {
61  state = S2; // lower path
62  } else {
63  state = S0; // upper path
64  }; // end else - if
65  out[loop]=1;
66  break;
67 
68  case S2: // if state S2
69  if (m_pathMemory2[loop]) {
70  state = S3; // lower path
71  } else {
72  state = S1; // upper path
73  }; // end else - if
74  out[loop]=0;
75  break;
76 
77  case S3: // if state S3
78  if (m_pathMemory3[loop]) {
79  state = S3; // lower path
80  } else {
81  state = S1; // upper path
82  }; // end else - if
83  out[loop]=1;
84  break;
85 
86  }; // end switch
87  }; // end for
88 
89 return(length);
90 }; // end function
91 
92 
93 
94 // function viterbiDecode
95 
96 void viterbiDecode (int n, int *data, int *m_pathMemory0, int *m_pathMemory1, int *m_pathMemory2, int *m_pathMemory3, int *m_pathMetric) {
97  int tempMetric[4];
98  int metric[8];
99  int loop;
100 
101  int m1;
102  int m2;
103 
104  metric[0]=(data[1]^0)+(data[0]^0);
105  metric[1]=(data[1]^1)+(data[0]^1);
106  metric[2]=(data[1]^1)+(data[0]^0);
107  metric[3]=(data[1]^0)+(data[0]^1);
108  metric[4]=(data[1]^1)+(data[0]^1);
109  metric[5]=(data[1]^0)+(data[0]^0);
110  metric[6]=(data[1]^0)+(data[0]^1);
111  metric[7]=(data[1]^1)+(data[0]^0);
112 
113  // Pres. state = S0, Prev. state = S0 & S2
114  m1=metric[0]+m_pathMetric[0];
115  m2=metric[4]+m_pathMetric[2];
116  if (m1<m2) {
117  m_pathMemory0[n]=0;
118  tempMetric[0]=m1;
119  } else {
120  m_pathMemory0[n]=1;
121  tempMetric[0]=m2;
122  }; // end else - if
123 
124  // Pres. state = S1, Prev. state = S0 & S2
125  m1=metric[1]+m_pathMetric[0];
126  m2=metric[5]+m_pathMetric[2];
127  if (m1<m2) {
128  m_pathMemory1[n]=0;
129  tempMetric[1]=m1;
130  } else {
131  m_pathMemory1[n]=1;
132  tempMetric[1]=m2;
133  }; // end else - if
134 
135  // Pres. state = S2, Prev. state = S2 & S3
136  m1=metric[2]+m_pathMetric[1];
137  m2=metric[6]+m_pathMetric[3];
138  if (m1<m2) {
139  m_pathMemory2[n]=0;
140  tempMetric[2]=m1;
141  } else {
142  m_pathMemory2[n]=1;
143  tempMetric[2]=m2;
144  }
145 
146  // Pres. state = S3, Prev. state = S1 & S3
147  m1=metric[3]+m_pathMetric[1];
148  m2=metric[7]+m_pathMetric[3];
149  if (m1 < m2) {
150  m_pathMemory3[n]=0;
151  tempMetric[3]=m1;
152  } else {
153  m_pathMemory3[n]=1;
154  tempMetric[3]=m2;
155  }; // end else - if
156 
157  for (loop=0;loop<4;loop++) {
158  m_pathMetric[loop]=tempMetric[loop];
159  }; // end for
160 
161 }; // end function ViterbiDecode
162 
163 
164 // function FECdecoder
165 // returns outlen
166 int FECdecoder (int * in, int * out) {
167 int outLen;
168 
169 int m_pathMemory0[330];
170 int m_pathMemory1[330];
171 int m_pathMemory2[330];
172 int m_pathMemory3[330];
173 int m_pathMetric[4];
174 
175 int loop,loop2;
176 
177 int n=0;
178 
179 memset(m_pathMemory0,0,330*sizeof(int));
180 memset(m_pathMemory1,0,330*sizeof(int));
181 memset(m_pathMemory2,0,330*sizeof(int));
182 memset(m_pathMemory3,0,330*sizeof(int));
183 
184 for (loop=0;loop<4;loop++) {
185  m_pathMetric[loop]=0;
186 }; // end for
187 
188 
189 for (loop2=0;loop2<660;loop2+=2, n++) {
190  int data[2];
191 
192  if (in[loop2]) {
193  data[1]=1;
194  } else {
195  data[1]=0;
196  }; // end else - if
197 
198  if (in[loop2+1]) {
199  data[0]=1;
200  } else {
201  data[0]=0;
202  }; // end else - if
203 
204  viterbiDecode(n, data, m_pathMemory0, m_pathMemory1, m_pathMemory2, m_pathMemory3, m_pathMetric);
205 }; // end for
206 
207 outLen=traceBack(out, m_pathMemory0, m_pathMemory1, m_pathMemory2, m_pathMemory3);
208 
209 // Swap endian-ness
210 // code removed (done converting bits into octets), done in main program
211 
212 //for (loop=0;loop<330;loop+=8) {
213 // int temp;
214 // temp=out[loop];out[loop]=out[loop+7];out[loop+7]=temp;
215 // temp=out[loop+1];out[loop+1]=out[loop+6];out[loop+6]=temp;
216 // temp=out[loop+2];out[loop+2]=out[loop+5];out[loop+5]=temp;
217 // temp=out[loop+3];out[loop+3]=out[loop+4];out[loop+4]=temp;
218 //}
219 
220 return(outLen);
221 
222 }; // end function FECdecoder
223 
224 
225 // function deinterleave
226 void deinterleave (int * in, int * out) {
227 
228 int k=0;
229 int loop=0;
230 // function starts here
231 
232 // init vars
233 k=0;
234 
235 for (loop=0;loop<660;loop++) {
236  out[k]=in[loop];
237 
238  k += 24;
239 
240  if (k >= 672) {
241  k -= 671;
242  } else if (k >= 660) {
243  k -= 647;
244  }; // end elsif - if
245 }; // end for
246 
247 }; // end function deinterleave
248 
249 
250 
251 /// function scramble
252 
253 void scramble (int * in,int * out) {
254 
255 static const int SCRAMBLER_TABLE_BITS[] = {
256  0,0,0,0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,
257  0,0,1,0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,
258  1,1,0,1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,
259  1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,
260  0,0,0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,
261  0,1,0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,
262  1,0,1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1,
263  1,1,1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,
264  0,0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,
265  1,0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1,
266  0,1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1,
267  1,1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,
268  0,1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,1,
269  0,0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,
270  1,0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1,1,
271  1,1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,
272  1,1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,
273  0,1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,1,
274  0,1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,1,0,1,1,1,1,
275  1,0,1,0,0,1,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,0,0,0,0,1,
276  1,1,0,1,1,1,1,0,0,1,0,1,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,
277  1,1,0,0,0,1,0,1,1,1,0,1,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0,1,1,0,1,0,
278  1,0,0,1,1,1,0,0,1,1,1,1,0,1,1,0};
279 
280 const int SCRAMBLER_TABLE_BITS_LENGTH=720;
281 
282 int loop=0;
283 int m_count=0;
284 
285 
286 for (loop=0; loop < 660; loop++) {
287  out[loop] = in[loop] ^ SCRAMBLER_TABLE_BITS[m_count++];
288 
289  if (m_count >= SCRAMBLER_TABLE_BITS_LENGTH) {
290  m_count = 0U;
291  }; // end if
292 }; // end for
293 
294 }; // end function scramble
295 
296 
297 
298 
int FECdecoder(int *in, int *out)
Definition: descramble.h:166
void scramble(int *in, int *out)
function scramble
Definition: descramble.h:253
int traceBack(int *out, int *m_pathMemory0, int *m_pathMemory1, int *m_pathMemory2, int *m_pathMemory3)
Definition: descramble.h:40
void viterbiDecode(int n, int *data, int *m_pathMemory0, int *m_pathMemory1, int *m_pathMemory2, int *m_pathMemory3, int *m_pathMetric)
Definition: descramble.h:96
void deinterleave(int *in, int *out)
Definition: descramble.h:226