blob: 715a146237ee20425121fa866e38c1021ac741f3 [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):
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700132 items = []
133
Harald Welteeea18a62016-04-29 15:18:35 +0200134 for state in range(num_states):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700135 if pack:
136 x = pack(self.next_term_output(state))
137 else:
138 x = self.next_term_state(state)
139
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700140 items.append(x)
141
142 # Up to 12 numbers should be placed per line
143 print_formatted(items, "%3d, ", 12, fi)
Harald Welteeea18a62016-04-29 15:18:35 +0200144
145 def _print_x(self, fi, num_states, pack = False):
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700146 items = []
147
Harald Welteeea18a62016-04-29 15:18:35 +0200148 for state in range(num_states):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700149 if pack:
150 x0 = pack(self.next_output(state, 0))
151 x1 = pack(self.next_output(state, 1))
152 else:
153 x0 = self.next_state(state, 0)
154 x1 = self.next_state(state, 1)
155
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700156 items.append((x0, x1))
157
158 # Up to 4 blocks should be placed per line
159 print_formatted(items, "{ %2d, %2d }, ", 4, fi)
160
161 def _print_puncture(self, fi):
162 # Up to 12 numbers should be placed per line
163 print_formatted(self.puncture, "%3d, ", 12, fi)
Harald Welteeea18a62016-04-29 15:18:35 +0200164
165 def gen_tables(self, pref, fi):
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700166 pack = lambda n: \
167 sum([x << (self.rate_inv - i - 1) for i, x in enumerate(n)])
Harald Welteeea18a62016-04-29 15:18:35 +0200168 num_states = 1 << (self.k - 1)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700169
170 print >>fi, \
171 "\nstatic const uint8_t %s_state[][2] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200172 self._print_x(fi, num_states)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700173 print >>fi, \
174 "};\n\nstatic const uint8_t %s_output[][2] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200175 self._print_x(fi, num_states, pack)
176 print >>fi, "};"
177
178 if self.recursive:
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700179 print >>fi, \
180 "\nstatic const uint8_t %s_term_state[] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200181 self._print_term(fi, num_states)
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700182
183 print >>fi, \
184 "};\n\nstatic const uint8_t %s_term_output[] = {" % self.name
Harald Welteeea18a62016-04-29 15:18:35 +0200185 self._print_term(fi, num_states, pack)
186 print >>fi, "};"
187
188 if len(self.puncture):
189 print >>fi, "\nstatic const int %s_puncture[] = {" % self.name
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700190 self._print_puncture(fi)
Harald Welteeea18a62016-04-29 15:18:35 +0200191 print >>fi, "};"
192
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700193 # Write description as a multi-line comment
194 if self.description is not None:
195 print >>fi, "\n/**"
196 for line in self.description:
197 print >>fi, " * %s" % line
198 print >>fi, " */"
199
200 # Print a final convolutional code definition
Harald Welteeea18a62016-04-29 15:18:35 +0200201 print >>fi, "const struct osmo_conv_code %s_%s = {" % (pref, self.name)
202 print >>fi, "\t.N = %d," % self.rate_inv
203 print >>fi, "\t.K = %d," % self.k
204 print >>fi, "\t.len = %d," % self.block_len
205 print >>fi, "\t.next_output = %s_output," % self.name
206 print >>fi, "\t.next_state = %s_state," % self.name
207 if self.recursive:
208 print >>fi, "\t.next_term_output = %s_term_output," % self.name
209 print >>fi, "\t.next_term_state = %s_term_state," % self.name
210 if len(self.puncture):
211 print >>fi, "\t.puncture = %s_puncture," % self.name
212 print >>fi, "};"
213
214poly = lambda *args: sum([(1 << x) for x in args])
215
216def combine(src, sel, nb):
217 x = src & sel
218 fn_xor = lambda x, y: x ^ y
219 return reduce(fn_xor, [(x >> n) & 1 for n in range(nb)])
220
Vadim Yanitskiy6908fa72016-09-07 22:34:53 +0700221def print_formatted(items, format, count, fi):
222 counter = 0
223
224 # Print initial indent
225 fi.write("\t")
226
227 for item in items:
228 if counter > 0 and counter % count == 0:
229 fi.write("\n\t")
230
231 fi.write(format % item)
232 counter += 1
233
234 fi.write("\n")
235
Harald Welteeea18a62016-04-29 15:18:35 +0200236# Polynomials according to 3GPP TS 05.03 Annex B
237G0 = poly(0, 3, 4)
238G1 = poly(0, 1, 3, 4)
239G2 = poly(0, 2, 4)
240G3 = poly(0, 1, 2, 3, 4)
241G4 = poly(0, 2, 3, 5, 6)
242G5 = poly(0, 1, 4, 6)
243G6 = poly(0, 1, 2, 3, 4, 6)
244G7 = poly(0, 1, 2, 3, 6)
245
246CCH_poly = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700247 ( G0, 1 ),
248 ( G1, 1 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200249]
250
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700251conv_codes = [
252 # xCCH definition
253 ConvolutionalCode(
254 224,
255 CCH_poly,
256 name = "xcch",
257 description = [
258 "xCCH convolutional code:",
259 "228 bits blocks, rate 1/2, k = 5",
260 "G0 = 1 + D3 + D4",
261 "G1 = 1 + D + D3 + D4",
262 ]
263 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200264
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700265 # CS2 definition
266 ConvolutionalCode(
267 290,
268 CCH_poly,
269 puncture = [
270 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71,
271 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131,
272 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195,
273 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255,
274 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315,
275 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379,
276 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439,
277 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499,
278 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559,
279 563, 571, 575, 579, 583, 587, -1
280 ],
281 name = "cs2",
282 description = [
283 "CS2 convolutional code:",
284 "G0 = 1 + D3 + D4",
285 "G1 = 1 + D + D3 + D4",
286 ]
287 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200288
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700289 # CS3 definition
290 ConvolutionalCode(
291 334,
292 CCH_poly,
293 puncture = [
294 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53,
295 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95,
296 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137,
297 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179,
298 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221,
299 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263,
300 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305,
301 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347,
302 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389,
303 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431,
304 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473,
305 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515,
306 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557,
307 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599,
308 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641,
309 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1
310 ],
311 name = "cs3",
312 description = [
313 "CS3 convolutional code:",
314 "G0 = 1 + D3 + D4",
315 "G1 = 1 + D + D3 + D4",
316 ]
317 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200318
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700319 # TCH_AFS_12_2 definition
320 ConvolutionalCode(
321 250,
322 [
323 ( 1, 1 ),
324 ( G1, G0 ),
325 ],
326 puncture = [
327 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363,
328 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401,
329 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441,
330 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477,
331 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507,
332 -1
333 ],
334 name = 'tch_afs_12_2',
335 description = [
336 "TCH/AFS 12.2 kbits convolutional code:",
337 "250 bits block, rate 1/2, punctured",
338 "G0/G0 = 1",
339 "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4",
340 ]
341 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200342
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700343 # TCH_AFS_10_2 definition
344 ConvolutionalCode(
345 210,
346 [
347 ( G1, G3 ),
348 ( G2, G3 ),
349 ( 1, 1 ),
350 ],
351 puncture = [
352 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43,
353 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91,
354 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139,
355 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187,
356 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235,
357 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283,
358 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328,
359 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364,
360 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
361 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436,
362 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472,
363 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508,
364 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544,
365 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580,
366 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613,
367 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637,
368 639, 640, -1
369 ],
370 name = 'tch_afs_10_2',
371 description = [
372 "TCH/AFS 10.2 kbits convolutional code:",
373 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
374 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
375 "G3/G3 = 1",
376 ]
377 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200378
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700379 # TCH_AFS_7_95 definition
380 ConvolutionalCode(
381 165,
382 [
383 ( 1, 1 ),
384 ( G5, G4 ),
385 ( G6, G4 ),
386 ],
387 puncture = [
388 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
389 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
390 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
391 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
392 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
393 506, 508, 509, 511, 512, -1
394 ],
395 name = 'tch_afs_7_95',
396 description = [
397 "TCH/AFS 7.95 kbits convolutional code:",
398 "G4/G4 = 1",
399 "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6",
400 "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6",
401 ]
402 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200403
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700404 # TCH_AFS_7_4 definition
405 ConvolutionalCode(
406 154,
407 [
408 ( G1, G3 ),
409 ( G2, G3 ),
410 ( 1, 1 ),
411 ],
412 puncture = [
413 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415,
414 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469,
415 471, 472, -1
416 ],
417 name = 'tch_afs_7_4',
418 description = [
419 "TCH/AFS 7.4 kbits convolutional code:",
420 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
421 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
422 "G3/G3 = 1",
423 ]
424 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200425
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700426 # TCH_AFS_6_7 definition
427 ConvolutionalCode(
428 140,
429 [
430 ( G1, G3 ),
431 ( G2, G3 ),
432 ( 1, 1 ),
433 ( 1, 1 ),
434 ],
435 puncture = [
436 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107,
437 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267,
438 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327,
439 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371,
440 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403,
441 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435,
442 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467,
443 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499,
444 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531,
445 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559,
446 561, 563, 565, 567, 569, 571, 573, 575, -1
447 ],
448 name = 'tch_afs_6_7',
449 description = [
450 "TCH/AFS 6.7 kbits convolutional code:",
451 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
452 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
453 "G3/G3 = 1",
454 "G3/G3 = 1",
455 ]
456 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200457
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700458 # TCH_AFS_5_9 definition
459 ConvolutionalCode(
460 124,
461 [
462 ( G4, G6 ),
463 ( G5, G6 ),
464 ( 1, 1),
465 ( 1, 1),
466 ],
467 puncture = [
468 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95,
469 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287,
470 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375,
471 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439,
472 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491,
473 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519,
474 -1
475 ],
476 name = 'tch_afs_5_9',
477 description = [
478 "TCH/AFS 5.9 kbits convolutional code:",
479 "124 bits",
480 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
481 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
482 "G6/G6 = 1",
483 "G6/G6 = 1",
484 ]
485 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200486
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700487 # TCH_AFS_5_15 definition
488 ConvolutionalCode(
489 109,
490 [
491 ( G1, G3 ),
492 ( G1, G3 ),
493 ( G2, G3 ),
494 ( 1, 1 ),
495 ( 1, 1 ),
496 ],
497 puncture = [
498 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40,
499 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
500 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280,
501 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345,
502 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385,
503 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425,
504 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465,
505 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505,
506 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540,
507 544, 545, 549, 550, 554, 555, 559, 560, 564, -1
508 ],
509 name = 'tch_afs_5_15',
510 description = [
511 "TCH/AFS 5.15 kbits convolutional code:",
512 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
513 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
514 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
515 "G3/G3 = 1",
516 "G3/G3 = 1",
517 ]
518 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200519
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700520 # TCH_AFS_4_75 definition
521 ConvolutionalCode(
522 101,
523 [
524 ( G4, G6 ),
525 ( G4, G6 ),
526 ( G5, G6 ),
527 ( 1, 1 ),
528 ( 1, 1 ),
529 ],
530 puncture = [
531 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55,
532 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175,
533 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295,
534 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405,
535 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460,
536 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509,
537 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530,
538 531, 532, 534, -1
539 ],
540 name = 'tch_afs_4_75',
541 description = [
542 "TCH/AFS 4.75 kbits convolutional code:",
543 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
544 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
545 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
546 "G6/G6 = 1",
547 "G6/G6 = 1",
548 ]
549 )
550]
Harald Welteeea18a62016-04-29 15:18:35 +0200551
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700552if __name__ == '__main__':
553 path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
554 prefix = "gsm0503"
555
556 print >>sys.stderr, "Generating convolutional codes..."
557
558 # Open a new file for writing
559 f = open(os.path.join(path, "gsm0503_conv.c"), 'w')
Harald Welteeea18a62016-04-29 15:18:35 +0200560 print >>f, mod_license
561 print >>f, "#include <stdint.h>"
562 print >>f, "#include <osmocom/core/conv.h>"
Harald Welteeea18a62016-04-29 15:18:35 +0200563
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700564 # Generate the tables one by one
565 for code in conv_codes:
566 print >>sys.stderr, "Generate '%s' definition" % code.name
567 code.gen_tables(prefix, f)
568
569 print >>sys.stderr, "Generation complete."