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
40int 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
89return(length);
90}; // end function
91
92
93
94// function viterbiDecode
95
96void 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
166int FECdecoder (int * in, int * out) {
167int outLen;
168
169int m_pathMemory0[330];
170int m_pathMemory1[330];
171int m_pathMemory2[330];
172int m_pathMemory3[330];
173int m_pathMetric[4];
174
175int loop,loop2;
176
177int n=0;
178
179memset(m_pathMemory0,0,330*sizeof(int));
180memset(m_pathMemory1,0,330*sizeof(int));
181memset(m_pathMemory2,0,330*sizeof(int));
182memset(m_pathMemory3,0,330*sizeof(int));
183
184for (loop=0;loop<4;loop++) {
185 m_pathMetric[loop]=0;
186}; // end for
187
188
189for (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
207outLen=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
220return(outLen);
221
222}; // end function FECdecoder
223
224
225// function deinterleave
226void deinterleave (int * in, int * out) {
227
228int k=0;
229int loop=0;
230// function starts here
231
232// init vars
233k=0;
234
235for (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
253void scramble (int * in,int * out) {
254
255static 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
280const int SCRAMBLER_TABLE_BITS_LENGTH=720;
281
282int loop=0;
283int m_count=0;
284
285
286for (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
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
int traceBack(int *out, int *m_pathMemory0, int *m_pathMemory1, int *m_pathMemory2, int *m_pathMemory3)
Definition descramble.h:40
void deinterleave(int *in, int *out)
Definition descramble.h:226