blob: a4f918fdea61ef64cf1c25814a2623b236f576b7 [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 Yanitskiye31cf802016-09-07 21:51:25 +0700225# xCCH definition
Harald Welteeea18a62016-04-29 15:18:35 +0200226xCCH = ConvolutionalCode(
227 224,
228 CCH_poly,
229 name = "xcch",
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700230 description = [
231 "xCCH convolutional code:",
232 "228 bits blocks, rate 1/2, k = 5",
233 "G0 = 1 + D3 + D4",
234 "G1 = 1 + D + D3 + D4",
235 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200236)
237
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700238# CS2 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200239CS2 = ConvolutionalCode(
240 290,
241 CCH_poly,
242 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700243 15, 19, 23, 27, 31, 35, 43, 47, 51, 55, 59, 63, 67, 71,
244 75, 79, 83, 91, 95, 99, 103, 107, 111, 115, 119, 123, 127, 131,
245 139, 143, 147, 151, 155, 159, 163, 167, 171, 175, 179, 187, 191, 195,
246 199, 203, 207, 211, 215, 219, 223, 227, 235, 239, 243, 247, 251, 255,
247 259, 263, 267, 271, 275, 283, 287, 291, 295, 299, 303, 307, 311, 315,
248 319, 323, 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 371, 379,
249 383, 387, 391, 395, 399, 403, 407, 411, 415, 419, 427, 431, 435, 439,
250 443, 447, 451, 455, 459, 463, 467, 475, 479, 483, 487, 491, 495, 499,
251 503, 507, 511, 515, 523, 527, 531, 535, 539, 543, 547, 551, 555, 559,
252 563, 571, 575, 579, 583, 587, -1
253 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200254 name = "cs2",
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700255 description = [
256 "CS2 convolutional code:",
257 "G0 = 1 + D3 + D4",
258 "G1 = 1 + D + D3 + D4",
259 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200260)
261
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700262# CS3 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200263CS3 = ConvolutionalCode(
264 334,
265 CCH_poly,
266 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700267 15, 17, 21, 23, 27, 29, 33, 35, 39, 41, 45, 47, 51, 53,
268 57, 59, 63, 65, 69, 71, 75, 77, 81, 83, 87, 89, 93, 95,
269 99, 101, 105, 107, 111, 113, 117, 119, 123, 125, 129, 131, 135, 137,
270 141, 143, 147, 149, 153, 155, 159, 161, 165, 167, 171, 173, 177, 179,
271 183, 185, 189, 191, 195, 197, 201, 203, 207, 209, 213, 215, 219, 221,
272 225, 227, 231, 233, 237, 239, 243, 245, 249, 251, 255, 257, 261, 263,
273 267, 269, 273, 275, 279, 281, 285, 287, 291, 293, 297, 299, 303, 305,
274 309, 311, 315, 317, 321, 323, 327, 329, 333, 335, 339, 341, 345, 347,
275 351, 353, 357, 359, 363, 365, 369, 371, 375, 377, 381, 383, 387, 389,
276 393, 395, 399, 401, 405, 407, 411, 413, 417, 419, 423, 425, 429, 431,
277 435, 437, 441, 443, 447, 449, 453, 455, 459, 461, 465, 467, 471, 473,
278 477, 479, 483, 485, 489, 491, 495, 497, 501, 503, 507, 509, 513, 515,
279 519, 521, 525, 527, 531, 533, 537, 539, 543, 545, 549, 551, 555, 557,
280 561, 563, 567, 569, 573, 575, 579, 581, 585, 587, 591, 593, 597, 599,
281 603, 605, 609, 611, 615, 617, 621, 623, 627, 629, 633, 635, 639, 641,
282 645, 647, 651, 653, 657, 659, 663, 665, 669, 671, -1
283 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200284 name = "cs3",
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700285 description = [
286 "CS3 convolutional code:",
287 "G0 = 1 + D3 + D4",
288 "G1 = 1 + D + D3 + D4",
289 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200290)
291
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700292# TCH_AFS_12_2 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200293TCH_AFS_12_2 = ConvolutionalCode(
294 250,
295 [
296 ( 1, 1 ),
297 ( G1, G0 ),
298 ],
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700299 puncture = [
300 321, 325, 329, 333, 337, 341, 345, 349, 353, 357, 361, 363,
301 365, 369, 373, 377, 379, 381, 385, 389, 393, 395, 397, 401,
302 405, 409, 411, 413, 417, 421, 425, 427, 429, 433, 437, 441,
303 443, 445, 449, 453, 457, 459, 461, 465, 469, 473, 475, 477,
304 481, 485, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507,
305 -1
306 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200307 name = 'tch_afs_12_2',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700308 description = [
309 "TCH/AFS 12.2 kbits convolutional code:",
310 "250 bits block, rate 1/2, punctured",
311 "G0/G0 = 1",
312 "G1/G0 = 1 + D + D3 + D4 / 1 + D3 + D4",
313 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200314)
315
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700316# TCH_AFS_10_2 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200317TCH_AFS_10_2 = ConvolutionalCode(
318 210,
319 [
320 ( G1, G3 ),
321 ( G2, G3 ),
322 ( 1, 1 ),
323 ],
324 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700325 1, 4, 7, 10, 16, 19, 22, 28, 31, 34, 40, 43,
326 46, 52, 55, 58, 64, 67, 70, 76, 79, 82, 88, 91,
327 94, 100, 103, 106, 112, 115, 118, 124, 127, 130, 136, 139,
328 142, 148, 151, 154, 160, 163, 166, 172, 175, 178, 184, 187,
329 190, 196, 199, 202, 208, 211, 214, 220, 223, 226, 232, 235,
330 238, 244, 247, 250, 256, 259, 262, 268, 271, 274, 280, 283,
331 286, 292, 295, 298, 304, 307, 310, 316, 319, 322, 325, 328,
332 331, 334, 337, 340, 343, 346, 349, 352, 355, 358, 361, 364,
333 367, 370, 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
334 403, 406, 409, 412, 415, 418, 421, 424, 427, 430, 433, 436,
335 439, 442, 445, 448, 451, 454, 457, 460, 463, 466, 469, 472,
336 475, 478, 481, 484, 487, 490, 493, 496, 499, 502, 505, 508,
337 511, 514, 517, 520, 523, 526, 529, 532, 535, 538, 541, 544,
338 547, 550, 553, 556, 559, 562, 565, 568, 571, 574, 577, 580,
339 583, 586, 589, 592, 595, 598, 601, 604, 607, 609, 610, 613,
340 616, 619, 621, 622, 625, 627, 628, 631, 633, 634, 636, 637,
341 639, 640, -1
342 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200343 name = 'tch_afs_10_2',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700344 description = [
345 "TCH/AFS 10.2 kbits convolutional code:",
346 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
347 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
348 "G3/G3 = 1",
349 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200350)
351
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700352# TCH_AFS_7_95 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200353TCH_AFS_7_95 = ConvolutionalCode(
354 165,
355 [
356 ( 1, 1 ),
357 ( G5, G4 ),
358 ( G6, G4 ),
359 ],
360 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700361 1, 2, 4, 5, 8, 22, 70, 118, 166, 214, 262, 310,
362 317, 319, 325, 332, 334, 341, 343, 349, 356, 358, 365, 367,
363 373, 380, 382, 385, 389, 391, 397, 404, 406, 409, 413, 415,
364 421, 428, 430, 433, 437, 439, 445, 452, 454, 457, 461, 463,
365 469, 476, 478, 481, 485, 487, 490, 493, 500, 502, 503, 505,
366 506, 508, 509, 511, 512, -1
367 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200368 name = 'tch_afs_7_95',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700369 description = [
370 "TCH/AFS 7.95 kbits convolutional code:",
371 "G4/G4 = 1",
372 "G5/G4 = 1 + D + D4 + D6 / 1 + D2 + D3 + D5 + D6",
373 "G6/G4 = 1 + D + D2 + D3 + D4 + D6 / 1 + D2 + D3 + D5 + D6",
374 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200375)
376
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700377# TCH_AFS_7_4 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200378TCH_AFS_7_4 = ConvolutionalCode(
379 154,
380 [
381 ( G1, G3 ),
382 ( G2, G3 ),
383 ( 1, 1 ),
384 ],
385 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700386 0, 355, 361, 367, 373, 379, 385, 391, 397, 403, 409, 415,
387 421, 427, 433, 439, 445, 451, 457, 460, 463, 466, 468, 469,
388 471, 472, -1
389 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200390 name = 'tch_afs_7_4',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700391 description = [
392 "TCH/AFS 7.4 kbits convolutional code:",
393 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
394 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
395 "G3/G3 = 1",
396 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200397)
398
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700399# TCH_AFS_6_7 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200400TCH_AFS_6_7 = ConvolutionalCode(
401 140,
402 [
403 ( G1, G3 ),
404 ( G2, G3 ),
405 ( 1, 1 ),
406 ( 1, 1 ),
407 ],
408 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700409 1, 3, 7, 11, 15, 27, 39, 55, 67, 79, 95, 107,
410 119, 135, 147, 159, 175, 187, 199, 215, 227, 239, 255, 267,
411 279, 287, 291, 295, 299, 303, 307, 311, 315, 319, 323, 327,
412 331, 335, 339, 343, 347, 351, 355, 359, 363, 367, 369, 371,
413 375, 377, 379, 383, 385, 387, 391, 393, 395, 399, 401, 403,
414 407, 409, 411, 415, 417, 419, 423, 425, 427, 431, 433, 435,
415 439, 441, 443, 447, 449, 451, 455, 457, 459, 463, 465, 467,
416 471, 473, 475, 479, 481, 483, 487, 489, 491, 495, 497, 499,
417 503, 505, 507, 511, 513, 515, 519, 521, 523, 527, 529, 531,
418 535, 537, 539, 543, 545, 547, 549, 551, 553, 555, 557, 559,
419 561, 563, 565, 567, 569, 571, 573, 575, -1
420 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200421 name = 'tch_afs_6_7',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700422 description = [
423 "TCH/AFS 6.7 kbits convolutional code:",
424 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
425 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
426 "G3/G3 = 1",
427 "G3/G3 = 1",
428 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200429)
430
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700431# TCH_AFS_5_9 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200432TCH_AFS_5_9 = ConvolutionalCode(
433 124,
434 [
435 ( G4, G6 ),
436 ( G5, G6 ),
437 ( 1, 1),
438 ( 1, 1),
439 ],
440 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700441 0, 1, 3, 5, 7, 11, 15, 31, 47, 63, 79, 95,
442 111, 127, 143, 159, 175, 191, 207, 223, 239, 255, 271, 287,
443 303, 319, 327, 331, 335, 343, 347, 351, 359, 363, 367, 375,
444 379, 383, 391, 395, 399, 407, 411, 415, 423, 427, 431, 439,
445 443, 447, 455, 459, 463, 467, 471, 475, 479, 483, 487, 491,
446 495, 499, 503, 507, 509, 511, 512, 513, 515, 516, 517, 519,
447 -1
448 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200449 name = 'tch_afs_5_9',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700450 description = [
451 "TCH/AFS 5.9 kbits convolutional code:",
452 "124 bits",
453 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
454 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
455 "G6/G6 = 1",
456 "G6/G6 = 1",
457 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200458)
459
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700460# TCH_AFS_5_15 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200461TCH_AFS_5_15 = ConvolutionalCode(
462 109,
463 [
464 ( G1, G3 ),
465 ( G1, G3 ),
466 ( G2, G3 ),
467 ( 1, 1 ),
468 ( 1, 1 ),
469 ],
470 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700471 0, 4, 5, 9, 10, 14, 15, 20, 25, 30, 35, 40,
472 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160,
473 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280,
474 290, 300, 310, 315, 320, 325, 330, 334, 335, 340, 344, 345,
475 350, 354, 355, 360, 364, 365, 370, 374, 375, 380, 384, 385,
476 390, 394, 395, 400, 404, 405, 410, 414, 415, 420, 424, 425,
477 430, 434, 435, 440, 444, 445, 450, 454, 455, 460, 464, 465,
478 470, 474, 475, 480, 484, 485, 490, 494, 495, 500, 504, 505,
479 510, 514, 515, 520, 524, 525, 529, 530, 534, 535, 539, 540,
480 544, 545, 549, 550, 554, 555, 559, 560, 564, -1
481 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200482 name = 'tch_afs_5_15',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700483 description = [
484 "TCH/AFS 5.15 kbits convolutional code:",
485 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
486 "G1/G3 = 1 + D + D3 + D4 / 1 + D + D2 + D3 + D4",
487 "G2/G3 = 1 + D2 + D4 / 1 + D + D2 + D3 + D4",
488 "G3/G3 = 1",
489 "G3/G3 = 1",
490 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200491)
492
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700493# TCH_AFS_4_75 definition
Harald Welteeea18a62016-04-29 15:18:35 +0200494TCH_AFS_4_75 = ConvolutionalCode(
495 101,
496 [
497 ( G4, G6 ),
498 ( G4, G6 ),
499 ( G5, G6 ),
500 ( 1, 1 ),
501 ( 1, 1 ),
502 ],
503 puncture = [
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700504 0, 1, 2, 4, 5, 7, 9, 15, 25, 35, 45, 55,
505 65, 75, 85, 95, 105, 115, 125, 135, 145, 155, 165, 175,
506 185, 195, 205, 215, 225, 235, 245, 255, 265, 275, 285, 295,
507 305, 315, 325, 335, 345, 355, 365, 375, 385, 395, 400, 405,
508 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 459, 460,
509 465, 470, 475, 479, 480, 485, 490, 495, 499, 500, 505, 509,
510 510, 515, 517, 519, 520, 522, 524, 525, 526, 527, 529, 530,
511 531, 532, 534, -1
512 ],
Harald Welteeea18a62016-04-29 15:18:35 +0200513 name = 'tch_afs_4_75',
Vadim Yanitskiye31cf802016-09-07 21:51:25 +0700514 description = [
515 "TCH/AFS 4.75 kbits convolutional code:",
516 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
517 "G4/G6 = 1 + D2 + D3 + D5 + D6 / 1 + D + D2 + D3 + D4 + D6",
518 "G5/G6 = 1 + D + D4 + D6 / 1 + D + D2 + D3 + D4 + D6",
519 "G6/G6 = 1",
520 "G6/G6 = 1",
521 ]
Harald Welteeea18a62016-04-29 15:18:35 +0200522)
523
524def gen_c(dest, pref, code):
525 f = open(os.path.join(dest, 'conv_' + code.name + '_gen.c'), 'w')
526 print >>f, mod_license
527 print >>f, "#include <stdint.h>"
528 print >>f, "#include <osmocom/core/conv.h>"
529 code.gen_tables(pref, f)
530
531if __name__ == '__main__':
532 print >>sys.stderr, "Generating convolutional codes..."
533 prefix = "gsm0503"
534 path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
535 gen_c(path, prefix, xCCH)
536 gen_c(path, prefix, CS2)
537 gen_c(path, prefix, CS3)
538 gen_c(path, prefix, TCH_AFS_12_2)
539 gen_c(path, prefix, TCH_AFS_10_2)
540 gen_c(path, prefix, TCH_AFS_7_95)
541 gen_c(path, prefix, TCH_AFS_7_4)
542 gen_c(path, prefix, TCH_AFS_6_7)
543 gen_c(path, prefix, TCH_AFS_5_9)
544 gen_c(path, prefix, TCH_AFS_5_15)
545 gen_c(path, prefix, TCH_AFS_4_75)
546 print >>sys.stderr, "\tdone."