blob: 38ea63b5113773cede9d0fa7fb4833a583809bbf [file] [log] [blame]
Holger Hans Peter Freyther3a96d282016-04-29 21:24:48 +02001#!/usr/bin/python2
Harald Welteeea18a62016-04-29 15:18:35 +02002
3mod_license = """
4/*
5 * Copyright (C) 2011-2016 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2016 sysmocom s.f.m.c. GmbH
7 *
8 * All Rights Reserved
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
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 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24"""
25
26import sys, os, math
27
28class ConvolutionalCode(object):
29
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070030 def __init__(self, block_len, polys, name,
31 description = None, puncture = []):
Harald Welteeea18a62016-04-29 15:18:35 +020032 # Save simple params
33 self.block_len = block_len
34 self.k = 1
35 self.puncture = puncture
36 self.rate_inv = len(polys)
37
38 # Infos
39 self.name = name
40 self.description = description
41
42 # Handle polynoms (and check for recursion)
43 self.polys = [(1, 1) if x[0] == x[1] else x for x in polys]
44
45 # Determine the polynomial degree
46 for (x, y) in polys:
47 self.k = max(self.k, int(math.floor(math.log(max(x, y), 2))))
48 self.k = self.k + 1
49
50 self.poly_divider = 1
51 rp = [x[1] for x in self.polys if x[1] != 1]
52 if rp:
53 if not all([x == rp[0] for x in rp]):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070054 raise ValueError("Bad polynoms: "
55 "Can't have multiple different divider polynoms!")
56
Harald Welteeea18a62016-04-29 15:18:35 +020057 if not all([x[0] == 1 for x in polys if x[1] == 1]):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070058 raise ValueError("Bad polynoms: "
59 "Can't have a '1' divider with a non '1' dividend "
60 "in a recursive code")
61
Harald Welteeea18a62016-04-29 15:18:35 +020062 self.poly_divider = rp[0]
63
64 @property
65 def recursive(self):
66 return self.poly_divider != 1
67
68 @property
69 def _state_mask(self):
70 return (1 << (self.k - 1)) - 1
71
72 def next_state(self, state, bit):
73 nb = combine(
74 (state << 1) | bit,
75 self.poly_divider,
76 self.k,
77 )
78 return ((state << 1) | nb) & self._state_mask
79
80 def next_term_state(self, state):
81 return (state << 1) & self._state_mask
82
83 def next_output(self, state, bit, ns = None):
84 # Next state bit
85 if ns is None:
86 ns = self.next_state(state, bit)
87
88 src = (ns & 1) | (state << 1)
89
90 # Scan polynoms
91 rv = []
92 for p_n, p_d in self.polys:
93 if self.recursive and p_d == 1:
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070094 # No choice ... (systematic output in recursive case)
95 o = bit
Harald Welteeea18a62016-04-29 15:18:35 +020096 else:
97 o = combine(src, p_n, self.k)
98 rv.append(o)
99
100 return rv
101
102 def next_term_output(self, state, ns = None):
103 # Next state bit
104 if ns is None:
105 ns = self.next_term_state(state)
106
107 src = (ns & 1) | (state << 1)
108
109 # Scan polynoms
110 rv = []
111 for p_n, p_d in self.polys:
112 if self.recursive and p_d == 1:
113 # Systematic output are replaced when in 'termination' mode
114 o = combine(src, self.poly_divider, self.k)
115 else:
116 o = combine(src, p_n, self.k)
117 rv.append(o)
118
119 return rv
120
121 def next(self, state, bit):
122 ns = self.next_state(state, bit)
123 nb = self.next_output(state, bit, ns = ns)
124 return ns, nb
125
126 def next_term(self, state):
127 ns = self.next_term_state(state)
128 nb = self.next_term_output(state, ns = ns)
129 return ns, nb
130
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700131 def _print_term(self, fi, num_states, pack = False):
Harald Welteeea18a62016-04-29 15:18:35 +0200132 d = []
133 for state in range(num_states):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700134 if pack:
135 x = pack(self.next_term_output(state))
136 else:
137 x = self.next_term_state(state)
138
Harald Welteeea18a62016-04-29 15:18:35 +0200139 d.append("%d, " % x)
140 print >>fi, "\t%s" % ''.join(d)
141
142 def _print_x(self, fi, num_states, pack = False):
143 for state in range(num_states):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700144 if pack:
145 x0 = pack(self.next_output(state, 0))
146 x1 = pack(self.next_output(state, 1))
147 else:
148 x0 = self.next_state(state, 0)
149 x1 = self.next_state(state, 1)
150
Harald Welteeea18a62016-04-29 15:18:35 +0200151 print >>fi, "\t{ %2d, %2d }," % (x0, x1)
152
153 def gen_tables(self, pref, fi):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700154 pack = lambda n: \
155 sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)])
Harald Welteeea18a62016-04-29 15:18:35 +0200156 num_states = 1 << (self.k - 1)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700157
158 print >>fi, \
159 "\nstatic const uint8_t %s_state[][2] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200160 self._print_x(fi, num_states)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700161 print >>fi, \
162 "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200163 self._print_x(fi, num_states, pack)
164 print >>fi, "};"
165
166 if self.recursive:
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700167 print >>fi, \
168 "\nstatic const uint8_t %s_term_state[] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200169 self._print_term(fi, num_states)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700170
171 print >>fi, \
172 "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200173 self._print_term(fi, num_states, pack)
174 print >>fi, "};"
175
176 if len(self.puncture):
177 print >>fi, "\nstatic const int %s_puncture[] = {" % self.name
178 for p in self.puncture:
179 print >>fi, "\t%d," % p
180 print >>fi, "};"
181
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700182 # Write description as a multi-line comment
183 if self.description is not None:
184 print >>fi, "\n/**"
185 for line in self.description:
186 print >>fi, " * %s" % line
187 print >>fi, " */"
188
189 # Print a final convolutional code definition
Harald Welteeea18a62016-04-29 15:18:35 +0200190 print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name)
191 print >>fi, "\t.N = %d," % self.rate_inv
192 print >>fi, "\t.K = %d," % self.k
193 print >>fi, "\t.len = %d," % self.block_len
194 print >>fi, "\t.next_output = %s_output," % self.name
195 print >>fi, "\t.next_state = %s_state," % self.name
196 if self.recursive:
197 print >>fi, "\t.next_term_output = %s_term_output," % self.name
198 print >>fi, "\t.next_term_state = %s_term_state," % self.name
199 if len(self.puncture):
200 print >>fi, "\t.puncture = %s_puncture," % self.name
201 print >>fi, "};"
202
203poly = lambda *args: sum([(1 << x) for x in args])
204
205def combine(src, sel, nb):
206 x = src & sel
207 fn_xor = lambda x, y: x ^ y
208 return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)])
209
210# Polynomials according to 3GPP TS 05.03 Annex B
211G0 = poly(0, 3, 4)
212G1 = poly(0, 1, 3, 4)
213G2 = poly(0, 2, 4)
214G3 = poly(0, 1, 2, 3, 4)
215G4 = poly(0, 2, 3, 5, 6)
216G5 = poly(0, 1, 4, 6)
217G6 = poly(0, 1, 2, 3, 4, 6)
218G7 = poly(0, 1, 2, 3, 6)
219
220CCH_poly = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700221 ( G0, 1 ),
222 ( G1, 1 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200223]
224
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700225conv_codes = [
226 # xCCH definition
227 ConvolutionalCode(
228 224,
229 CCH_poly,
230 name = "xcch",
231 description = [
232 "xCCH convolutional code:",
233 "228 bits blocks, rate 1/2, k = 5",
234 "G0 = 1 + D3 + D4",
235 "G1 = 1 + D + D3 + D4",
236 ]
237 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200238
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700239 # CS2 definition
240 ConvolutionalCode(
241 290,
242 CCH_poly,
243 puncture = [
244 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71,
245 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131,
246 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195,
247 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255,
248 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315,
249 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379,
250 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439,
251 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499,
252 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559,
253 563, 571, 575, 579, 583, 587, -1
254 ],
255 name = "cs2",
256 description = [
257 "CS2 convolutional code:",
258 "G0 = 1 + D3 + D4",
259 "G1 = 1 + D + D3 + D4",
260 ]
261 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200262
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700263 # CS3 definition
264 ConvolutionalCode(
265 334,
266 CCH_poly,
267 puncture = [
268 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53,
269 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95,
270 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137,
271 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179,
272 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221,
273 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263,
274 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305,
275 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347,
276 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389,
277 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431,
278 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473,
279 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515,
280 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557,
281 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599,
282 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641,
283 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1
284 ],
285 name = "cs3",
286 description = [
287 "CS3 convolutional code:",
288 "G0 = 1 + D3 + D4",
289 "G1 = 1 + D + D3 + D4",
290 ]
291 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200292
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700293 # TCH_AFS_12_2 definition
294 ConvolutionalCode(
295 250,
296 [
297 ( 1, 1 ),
298 ( G1, G0 ),
299 ],
300 puncture = [
301 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363,
302 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401,
303 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441,
304 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477,
305 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507,
306 -1
307 ],
308 name = 'tch_afs_12_2',
309 description = [
310 "TCH/AFS 12.2 kbits convolutional code:",
311 "250 bits block, rate 1/2, punctured",
312 "G0/G0 = 1",
313 "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4",
314 ]
315 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200316
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700317 # TCH_AFS_10_2 definition
318 ConvolutionalCode(
319 210,
320 [
321 ( G1, G3 ),
322 ( G2, G3 ),
323 ( 1, 1 ),
324 ],
325 puncture = [
326 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43,
327 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91,
328 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139,
329 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187,
330 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235,
331 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283,
332 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328,
333 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364,
334 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
335 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436,
336 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472,
337 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508,
338 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544,
339 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580,
340 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613,
341 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637,
342 639, 640, -1
343 ],
344 name = 'tch_afs_10_2',
345 description = [
346 "TCH/AFS 10.2 kbits convolutional code:",
347 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
348 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
349 "G3/G3 = 1",
350 ]
351 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200352
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700353 # TCH_AFS_7_95 definition
354 ConvolutionalCode(
355 165,
356 [
357 ( 1, 1 ),
358 ( G5, G4 ),
359 ( G6, G4 ),
360 ],
361 puncture = [
362 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
363 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
364 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
365 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
366 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
367 506, 508, 509, 511, 512, -1
368 ],
369 name = 'tch_afs_7_95',
370 description = [
371 "TCH/AFS 7.95 kbits convolutional code:",
372 "G4/G4 = 1",
373 "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6",
374 "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6",
375 ]
376 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200377
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700378 # TCH_AFS_7_4 definition
379 ConvolutionalCode(
380 154,
381 [
382 ( G1, G3 ),
383 ( G2, G3 ),
384 ( 1, 1 ),
385 ],
386 puncture = [
387 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415,
388 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469,
389 471, 472, -1
390 ],
391 name = 'tch_afs_7_4',
392 description = [
393 "TCH/AFS 7.4 kbits convolutional code:",
394 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
395 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
396 "G3/G3 = 1",
397 ]
398 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200399
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700400 # TCH_AFS_6_7 definition
401 ConvolutionalCode(
402 140,
403 [
404 ( G1, G3 ),
405 ( G2, G3 ),
406 ( 1, 1 ),
407 ( 1, 1 ),
408 ],
409 puncture = [
410 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107,
411 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267,
412 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327,
413 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371,
414 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403,
415 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435,
416 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467,
417 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499,
418 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531,
419 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559,
420 561, 563, 565, 567, 569, 571, 573, 575, -1
421 ],
422 name = 'tch_afs_6_7',
423 description = [
424 "TCH/AFS 6.7 kbits convolutional code:",
425 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
426 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
427 "G3/G3 = 1",
428 "G3/G3 = 1",
429 ]
430 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200431
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700432 # TCH_AFS_5_9 definition
433 ConvolutionalCode(
434 124,
435 [
436 ( G4, G6 ),
437 ( G5, G6 ),
438 ( 1, 1),
439 ( 1, 1),
440 ],
441 puncture = [
442 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95,
443 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287,
444 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375,
445 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439,
446 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491,
447 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519,
448 -1
449 ],
450 name = 'tch_afs_5_9',
451 description = [
452 "TCH/AFS 5.9 kbits convolutional code:",
453 "124 bits",
454 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
455 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
456 "G6/G6 = 1",
457 "G6/G6 = 1",
458 ]
459 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200460
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700461 # TCH_AFS_5_15 definition
462 ConvolutionalCode(
463 109,
464 [
465 ( G1, G3 ),
466 ( G1, G3 ),
467 ( G2, G3 ),
468 ( 1, 1 ),
469 ( 1, 1 ),
470 ],
471 puncture = [
472 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40,
473 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
474 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280,
475 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345,
476 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385,
477 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425,
478 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465,
479 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505,
480 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540,
481 544, 545, 549, 550, 554, 555, 559, 560, 564, -1
482 ],
483 name = 'tch_afs_5_15',
484 description = [
485 "TCH/AFS 5.15 kbits convolutional code:",
486 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
487 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
488 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
489 "G3/G3 = 1",
490 "G3/G3 = 1",
491 ]
492 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200493
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700494 # TCH_AFS_4_75 definition
495 ConvolutionalCode(
496 101,
497 [
498 ( G4, G6 ),
499 ( G4, G6 ),
500 ( G5, G6 ),
501 ( 1, 1 ),
502 ( 1, 1 ),
503 ],
504 puncture = [
505 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55,
506 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175,
507 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295,
508 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405,
509 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460,
510 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509,
511 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530,
512 531, 532, 534, -1
513 ],
514 name = 'tch_afs_4_75',
515 description = [
516 "TCH/AFS 4.75 kbits convolutional code:",
517 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
518 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
519 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
520 "G6/G6 = 1",
521 "G6/G6 = 1",
522 ]
523 )
524]
Harald Welteeea18a62016-04-29 15:18:35 +0200525
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700526if __name__ == '__main__':
527 path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
528 prefix = "gsm0503"
529
530 print >>sys.stderr, "Generating convolutional codes..."
531
532 # Open a new file for writing
533 f = open(os.path.join(path, "gsm0503_conv.c"), 'w')
Harald Welteeea18a62016-04-29 15:18:35 +0200534 print >>f, mod_license
535 print >>f, "#include <stdint.h>"
536 print >>f, "#include <osmocom/core/conv.h>"
Harald Welteeea18a62016-04-29 15:18:35 +0200537
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700538 # Generate the tables one by one
539 for code in conv_codes:
540 print >>sys.stderr, "Generate '%s' definition" % code.name
541 code.gen_tables(prefix, f)
542
543 print >>sys.stderr, "Generation complete."