blob: 865a5ee85c76b66229dc15601171a383a49a7017 [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
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +070042 # Handle polynomials (and check for recursion)
Harald Welteeea18a62016-04-29 15:18:35 +020043 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 Yanitskiy84fc2ce2016-09-08 20:30:36 +070054 raise ValueError("Bad polynomials: "
55 "Can't have multiple different divider polynomials!")
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070056
Harald Welteeea18a62016-04-29 15:18:35 +020057 if not all([x[0] == 1 for x in polys if x[1] == 1]):
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +070058 raise ValueError("Bad polynomials: "
Vadim Yanitskiye31cf802016-09-07 21:51:25 +070059 "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
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +070090 # Scan polynomials
Harald Welteeea18a62016-04-29 15:18:35 +020091 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
Vadim Yanitskiy84fc2ce2016-09-08 20:30:36 +0700109 # Scan polynomials
Harald Welteeea18a62016-04-29 15:18:35 +0200110 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 Yanitskiyf3d38c42016-09-07 23:09:49 +0700265 # RACH definition
266 ConvolutionalCode(
267 14,
268 CCH_poly,
269 name = "rach",
270 description = ["RACH convolutional code"]
271 ),
272
273 # SCH definition
274 ConvolutionalCode(
275 35,
276 CCH_poly,
277 name = "sch",
278 description = ["SCH convolutional code"]
279 ),
280
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700281 # CS2 definition
282 ConvolutionalCode(
283 290,
284 CCH_poly,
285 puncture = [
286 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71,
287 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131,
288 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195,
289 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255,
290 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315,
291 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379,
292 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439,
293 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499,
294 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559,
295 563, 571, 575, 579, 583, 587, -1
296 ],
297 name = "cs2",
298 description = [
299 "CS2 convolutional code:",
300 "G0 = 1 + D3 + D4",
301 "G1 = 1 + D + D3 + D4",
302 ]
303 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200304
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700305 # CS3 definition
306 ConvolutionalCode(
307 334,
308 CCH_poly,
309 puncture = [
310 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53,
311 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95,
312 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137,
313 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179,
314 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221,
315 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263,
316 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305,
317 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347,
318 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389,
319 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431,
320 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473,
321 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515,
322 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557,
323 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599,
324 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641,
325 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1
326 ],
327 name = "cs3",
328 description = [
329 "CS3 convolutional code:",
330 "G0 = 1 + D3 + D4",
331 "G1 = 1 + D + D3 + D4",
332 ]
333 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200334
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700335 # TCH_AFS_12_2 definition
336 ConvolutionalCode(
337 250,
338 [
339 ( 1, 1 ),
340 ( G1, G0 ),
341 ],
342 puncture = [
343 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363,
344 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401,
345 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441,
346 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477,
347 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507,
348 -1
349 ],
350 name = 'tch_afs_12_2',
351 description = [
352 "TCH/AFS 12.2 kbits convolutional code:",
353 "250 bits block, rate 1/2, punctured",
354 "G0/G0 = 1",
355 "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4",
356 ]
357 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200358
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700359 # TCH_AFS_10_2 definition
360 ConvolutionalCode(
361 210,
362 [
363 ( G1, G3 ),
364 ( G2, G3 ),
365 ( 1, 1 ),
366 ],
367 puncture = [
368 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43,
369 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91,
370 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139,
371 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187,
372 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235,
373 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283,
374 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328,
375 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364,
376 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
377 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436,
378 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472,
379 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508,
380 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544,
381 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580,
382 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613,
383 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637,
384 639, 640, -1
385 ],
386 name = 'tch_afs_10_2',
387 description = [
388 "TCH/AFS 10.2 kbits convolutional code:",
389 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
390 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
391 "G3/G3 = 1",
392 ]
393 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200394
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700395 # TCH_AFS_7_95 definition
396 ConvolutionalCode(
397 165,
398 [
399 ( 1, 1 ),
400 ( G5, G4 ),
401 ( G6, G4 ),
402 ],
403 puncture = [
404 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
405 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
406 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
407 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
408 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
409 506, 508, 509, 511, 512, -1
410 ],
411 name = 'tch_afs_7_95',
412 description = [
413 "TCH/AFS 7.95 kbits convolutional code:",
414 "G4/G4 = 1",
415 "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6",
416 "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6",
417 ]
418 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200419
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700420 # TCH_AFS_7_4 definition
421 ConvolutionalCode(
422 154,
423 [
424 ( G1, G3 ),
425 ( G2, G3 ),
426 ( 1, 1 ),
427 ],
428 puncture = [
429 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415,
430 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469,
431 471, 472, -1
432 ],
433 name = 'tch_afs_7_4',
434 description = [
435 "TCH/AFS 7.4 kbits convolutional code:",
436 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
437 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
438 "G3/G3 = 1",
439 ]
440 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200441
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700442 # TCH_AFS_6_7 definition
443 ConvolutionalCode(
444 140,
445 [
446 ( G1, G3 ),
447 ( G2, G3 ),
448 ( 1, 1 ),
449 ( 1, 1 ),
450 ],
451 puncture = [
452 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107,
453 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267,
454 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327,
455 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371,
456 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403,
457 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435,
458 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467,
459 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499,
460 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531,
461 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559,
462 561, 563, 565, 567, 569, 571, 573, 575, -1
463 ],
464 name = 'tch_afs_6_7',
465 description = [
466 "TCH/AFS 6.7 kbits convolutional code:",
467 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
468 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
469 "G3/G3 = 1",
470 "G3/G3 = 1",
471 ]
472 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200473
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700474 # TCH_AFS_5_9 definition
475 ConvolutionalCode(
476 124,
477 [
478 ( G4, G6 ),
479 ( G5, G6 ),
480 ( 1, 1),
481 ( 1, 1),
482 ],
483 puncture = [
484 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95,
485 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287,
486 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375,
487 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439,
488 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491,
489 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519,
490 -1
491 ],
492 name = 'tch_afs_5_9',
493 description = [
494 "TCH/AFS 5.9 kbits convolutional code:",
495 "124 bits",
496 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
497 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
498 "G6/G6 = 1",
499 "G6/G6 = 1",
500 ]
501 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200502
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700503 # TCH_AFS_5_15 definition
504 ConvolutionalCode(
505 109,
506 [
507 ( G1, G3 ),
508 ( G1, G3 ),
509 ( G2, G3 ),
510 ( 1, 1 ),
511 ( 1, 1 ),
512 ],
513 puncture = [
514 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40,
515 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
516 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280,
517 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345,
518 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385,
519 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425,
520 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465,
521 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505,
522 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540,
523 544, 545, 549, 550, 554, 555, 559, 560, 564, -1
524 ],
525 name = 'tch_afs_5_15',
526 description = [
527 "TCH/AFS 5.15 kbits convolutional code:",
528 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
529 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
530 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
531 "G3/G3 = 1",
532 "G3/G3 = 1",
533 ]
534 ),
Harald Welteeea18a62016-04-29 15:18:35 +0200535
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700536 # TCH_AFS_4_75 definition
537 ConvolutionalCode(
538 101,
539 [
540 ( G4, G6 ),
541 ( G4, G6 ),
542 ( G5, G6 ),
543 ( 1, 1 ),
544 ( 1, 1 ),
545 ],
546 puncture = [
547 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55,
548 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175,
549 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295,
550 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405,
551 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460,
552 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509,
553 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530,
554 531, 532, 534, -1
555 ],
556 name = 'tch_afs_4_75',
557 description = [
558 "TCH/AFS 4.75 kbits convolutional code:",
559 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
560 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
561 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
562 "G6/G6 = 1",
563 "G6/G6 = 1",
564 ]
Vadim Yanitskiyf3d38c42016-09-07 23:09:49 +0700565 ),
566
567 # TCH_FR definition
568 ConvolutionalCode(
569 185,
570 CCH_poly,
571 name = "tch_fr",
572 description = ["TCH/F convolutional code"]
573 ),
574
575 # TCH_HR definition
576 ConvolutionalCode(
577 98,
578 [
579 ( G4, 1 ),
580 ( G5, 1 ),
581 ( G6, 1 ),
582 ],
583 puncture = [
584 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34,
585 37, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70,
586 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106,
587 109, 112, 115, 118, 121, 124, 127, 130, 133, 136, 139, 142,
588 145, 148, 151, 154, 157, 160, 163, 166, 169, 172, 175, 178,
589 181, 184, 187, 190, 193, 196, 199, 202, 205, 208, 211, 214,
590 217, 220, 223, 226, 229, 232, 235, 238, 241, 244, 247, 250,
591 253, 256, 259, 262, 265, 268, 271, 274, 277, 280, 283, 295,
592 298, 301, 304, 307, 310, -1,
593 ],
594 name = "tch_hr",
595 description = ["TCH/H convolutional code"]
596 ),
597
598 # TCH_AHS_7_95 definition
599 ConvolutionalCode(
600 129,
601 [
602 ( 1, 1 ),
603 ( G1, G0 ),
604 ],
605 puncture = [
606 1, 3, 5, 7, 11, 15, 19, 23, 27, 31, 35, 43,
607 47, 51, 55, 59, 63, 67, 71, 79, 83, 87, 91, 95,
608 99, 103, 107, 115, 119, 123, 127, 131, 135, 139, 143, 151,
609 155, 159, 163, 167, 171, 175, 177, 179, 183, 185, 187, 191,
610 193, 195, 197, 199, 203, 205, 207, 211, 213, 215, 219, 221,
611 223, 227, 229, 231, 233, 235, 239, 241, 243, 247, 249, 251,
612 255, 257, 259, 261, 263, 265, -1,
613 ],
614 name = "tch_ahs_7_95",
615 description = ["TCH/AHS 7.95 kbits convolutional code"]
616 ),
617
618 # TCH_AHS_7_4 definition
619 ConvolutionalCode(
620 126,
621 [
622 ( 1, 1 ),
623 ( G1, G0 ),
624 ],
625 puncture = [
626 1, 3, 7, 11, 19, 23, 27, 35, 39, 43, 51, 55,
627 59, 67, 71, 75, 83, 87, 91, 99, 103, 107, 115, 119,
628 123, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171,
629 175, 179, 183, 187, 191, 195, 199, 203, 207, 211, 215, 219,
630 221, 223, 227, 229, 231, 235, 237, 239, 243, 245, 247, 251,
631 253, 255, 257, 259, -1,
632 ],
633 name = "tch_ahs_7_4",
634 description = ["TCH/AHS 7.4 kbits convolutional code"]
635 ),
636
637 # TCH_AHS_6_7 definition
638 ConvolutionalCode(
639 116,
640 [
641 ( 1, 1 ),
642 ( G1, G0 ),
643 ],
644 puncture = [
645 1, 3, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99,
646 109, 119, 129, 139, 149, 159, 167, 169, 177, 179, 187, 189,
647 197, 199, 203, 207, 209, 213, 217, 219, 223, 227, 229, 231,
648 233, 235, 237, 239, -1,
649 ],
650 name = "tch_ahs_6_7",
651 description = ["TCH/AHS 6.7 kbits convolutional code"]
652 ),
653
654 # TCH_AHS_5_9 definition
655 ConvolutionalCode(
656 108,
657 [
658 ( 1, 1 ),
659 ( G1, G0 ),
660 ],
661 puncture = [
662 1, 15, 71, 127, 139, 151, 163, 175, 187, 195, 203, 211,
663 215, 219, 221, 223, -1,
664 ],
665 name = "tch_ahs_5_9",
666 description = ["TCH/AHS 5.9 kbits convolutional code"]
667 ),
668
669 # TCH_AHS_5_15 definition
670 ConvolutionalCode(
671 97,
672 [
673 ( G1, G3 ),
674 ( G2, G3 ),
675 ( 1, 1 ),
676 ],
677 puncture = [
678 0, 1, 3, 4, 6, 9, 12, 15, 18, 21, 27, 33,
679 39, 45, 51, 54, 57, 63, 69, 75, 81, 87, 90, 93,
680 99, 105, 111, 117, 123, 126, 129, 135, 141, 147, 153, 159,
681 162, 165, 168, 171, 174, 177, 180, 183, 186, 189, 192, 195,
682 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231,
683 234, 237, 240, 243, 244, 246, 249, 252, 255, 256, 258, 261,
684 264, 267, 268, 270, 273, 276, 279, 280, 282, 285, 288, 289,
685 291, 294, 295, 297, 298, 300, 301, -1,
686 ],
687 name = "tch_ahs_5_15",
688 description = ["TCH/AHS 5.15 kbits convolutional code"]
689 ),
690
691 # TCH_AHS_4_75 definition
692 ConvolutionalCode(
693 89,
694 [
695 ( 1, 1 ),
696 ( G5, G4 ),
697 ( G6, G4 ),
698 ],
699 puncture = [
700 1, 2, 4, 5, 7, 8, 10, 13, 16, 22, 28, 34,
701 40, 46, 52, 58, 64, 70, 76, 82, 88, 94, 100, 106,
702 112, 118, 124, 130, 136, 142, 148, 151, 154, 160, 163, 166,
703 172, 175, 178, 184, 187, 190, 196, 199, 202, 208, 211, 214,
704 220, 223, 226, 232, 235, 238, 241, 244, 247, 250, 253, 256,
705 259, 262, 265, 268, 271, 274, 275, 277, 278, 280, 281, 283,
706 284, -1,
707 ],
708 name = "tch_ahs_4_75",
709 description = ["TCH/AHS 4.75 kbits convolutional code"]
710 ),
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700711]
Harald Welteeea18a62016-04-29 15:18:35 +0200712
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700713if __name__ == '__main__':
714 path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
715 prefix = "gsm0503"
716
717 print >>sys.stderr, "Generating convolutional codes..."
718
719 # Open a new file for writing
720 f = open(os.path.join(path, "gsm0503_conv.c"), 'w')
Harald Welteeea18a62016-04-29 15:18:35 +0200721 print >>f, mod_license
722 print >>f, "#include <stdint.h>"
723 print >>f, "#include <osmocom/core/conv.h>"
Harald Welteeea18a62016-04-29 15:18:35 +0200724
Vadim Yanitskiyd2d97602016-09-07 22:18:10 +0700725 # Generate the tables one by one
726 for code in conv_codes:
727 print >>sys.stderr, "Generate '%s' definition" % code.name
728 code.gen_tables(prefix, f)
729
730 print >>sys.stderr, "Generation complete."