blob: 5cc4f1487d43d13cbb1ae72230b8dcefee7fff0a [file] [log] [blame]
Neels Hofmeyr17518fe2017-06-20 04:35:06 +02001/*! \file gsm610.c
2 * GSM 06.10 - GSM FR codec. */
Sylvain Munaut1a4ea5b2010-10-08 15:09:16 +02003/*
4 * (C) 2010 Sylvain Munaut <tnt@246tNt.com>
5 *
6 * All Rights Reserved
7 *
Harald Weltee08da972017-11-13 01:00:26 +09008 * SPDX-License-Identifier: GPL-2.0+
9 *
Sylvain Munaut1a4ea5b2010-10-08 15:09:16 +020010 * 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 2 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 *
Sylvain Munaut1a4ea5b2010-10-08 15:09:16 +020020 */
21
22#include <stdint.h>
Maxec8f1922016-05-31 14:50:21 +020023#include <stdbool.h>
24
25#include <osmocom/core/bitvec.h>
26#include <osmocom/core/utils.h>
Harald Weltedee71722017-05-31 02:48:48 +020027#include <osmocom/codec/codec.h>
Sylvain Munaut1a4ea5b2010-10-08 15:09:16 +020028
29/* GSM FR - subjective importance bit ordering */
30 /* This array encodes GSM 05.03 Table 2.
31 * It's also GSM 06.10 Table A.2.1a
32 *
33 * It converts between serial parameter output by the encoder and the
34 * order needed before channel encoding.
35 */
Diego Elio Pettenò23431c72012-06-29 13:01:27 -070036const uint16_t gsm610_bitorder[260] = {
Sylvain Munaut1a4ea5b2010-10-08 15:09:16 +020037 0, /* LARc0:5 */
38 47, /* Xmaxc0:5 */
39 103, /* Xmaxc1:5 */
40 159, /* Xmaxc2:5 */
41 215, /* Xmaxc3:5 */
42 1, /* LARc0:4 */
43 6, /* LARc1:5 */
44 12, /* LARc2:4 */
45 2, /* LARc0:3 */
46 7, /* LARc1:4 */
47 13, /* LARc2:3 */
48 17, /* LARc3:4 */
49 36, /* Nc0:6 */
50 92, /* Nc1:6 */
51 148, /* Nc2:6 */
52 204, /* Nc3:6 */
53 48, /* Xmaxc0:4 */
54 104, /* Xmaxc1:4 */
55 160, /* Xmaxc2:4 */
56 216, /* Xmaxc3:4 */
57 8, /* LARc1:3 */
58 22, /* LARc4:3 */
59 26, /* LARc5:3 */
60 37, /* Nc0:5 */
61 93, /* Nc1:5 */
62 149, /* Nc2:5 */
63 205, /* Nc3:5 */
64 38, /* Nc0:4 */
65 94, /* Nc1:4 */
66 150, /* Nc2:4 */
67 206, /* Nc3:4 */
68 39, /* Nc0:3 */
69 95, /* Nc1:3 */
70 151, /* Nc2:3 */
71 207, /* Nc3:3 */
72 40, /* Nc0:2 */
73 96, /* Nc1:2 */
74 152, /* Nc2:2 */
75 208, /* Nc3:2 */
76 49, /* Xmaxc0:3 */
77 105, /* Xmaxc1:3 */
78 161, /* Xmaxc2:3 */
79 217, /* Xmaxc3:3 */
80 3, /* LARc0:2 */
81 18, /* LARc3:3 */
82 30, /* LARc6:2 */
83 41, /* Nc0:1 */
84 97, /* Nc1:1 */
85 153, /* Nc2:1 */
86 209, /* Nc3:1 */
87 23, /* LARc4:2 */
88 27, /* LARc5:2 */
89 43, /* bc0:1 */
90 99, /* bc1:1 */
91 155, /* bc2:1 */
92 211, /* bc3:1 */
93 42, /* Nc0:0 */
94 98, /* Nc1:0 */
95 154, /* Nc2:0 */
96 210, /* Nc3:0 */
97 45, /* Mc0:1 */
98 101, /* Mc1:1 */
99 157, /* Mc2:1 */
100 213, /* Mc3:1 */
101 4, /* LARc0:1 */
102 9, /* LARc1:2 */
103 14, /* LARc2:2 */
104 33, /* LARc7:2 */
105 19, /* LARc3:2 */
106 24, /* LARc4:1 */
107 31, /* LARc6:1 */
108 44, /* bc0:0 */
109 100, /* bc1:0 */
110 156, /* bc2:0 */
111 212, /* bc3:0 */
112 50, /* Xmaxc0:2 */
113 106, /* Xmaxc1:2 */
114 162, /* Xmaxc2:2 */
115 218, /* Xmaxc3:2 */
116 53, /* xmc0_0:2 */
117 56, /* xmc0_1:2 */
118 59, /* xmc0_2:2 */
119 62, /* xmc0_3:2 */
120 65, /* xmc0_4:2 */
121 68, /* xmc0_5:2 */
122 71, /* xmc0_6:2 */
123 74, /* xmc0_7:2 */
124 77, /* xmc0_8:2 */
125 80, /* xmc0_9:2 */
126 83, /* xmc0_10:2 */
127 86, /* xmc0_11:2 */
128 89, /* xmc0_12:2 */
129 109, /* xmc1_0:2 */
130 112, /* xmc1_1:2 */
131 115, /* xmc1_2:2 */
132 118, /* xmc1_3:2 */
133 121, /* xmc1_4:2 */
134 124, /* xmc1_5:2 */
135 127, /* xmc1_6:2 */
136 130, /* xmc1_7:2 */
137 133, /* xmc1_8:2 */
138 136, /* xmc1_9:2 */
139 139, /* xmc1_10:2 */
140 142, /* xmc1_11:2 */
141 145, /* xmc1_12:2 */
142 165, /* xmc2_0:2 */
143 168, /* xmc2_1:2 */
144 171, /* xmc2_2:2 */
145 174, /* xmc2_3:2 */
146 177, /* xmc2_4:2 */
147 180, /* xmc2_5:2 */
148 183, /* xmc2_6:2 */
149 186, /* xmc2_7:2 */
150 189, /* xmc2_8:2 */
151 192, /* xmc2_9:2 */
152 195, /* xmc2_10:2 */
153 198, /* xmc2_11:2 */
154 201, /* xmc2_12:2 */
155 221, /* xmc3_0:2 */
156 224, /* xmc3_1:2 */
157 227, /* xmc3_2:2 */
158 230, /* xmc3_3:2 */
159 233, /* xmc3_4:2 */
160 236, /* xmc3_5:2 */
161 239, /* xmc3_6:2 */
162 242, /* xmc3_7:2 */
163 245, /* xmc3_8:2 */
164 248, /* xmc3_9:2 */
165 251, /* xmc3_10:2 */
166 254, /* xmc3_11:2 */
167 257, /* xmc3_12:2 */
168 46, /* Mc0:0 */
169 102, /* Mc1:0 */
170 158, /* Mc2:0 */
171 214, /* Mc3:0 */
172 51, /* Xmaxc0:1 */
173 107, /* Xmaxc1:1 */
174 163, /* Xmaxc2:1 */
175 219, /* Xmaxc3:1 */
176 54, /* xmc0_0:1 */
177 57, /* xmc0_1:1 */
178 60, /* xmc0_2:1 */
179 63, /* xmc0_3:1 */
180 66, /* xmc0_4:1 */
181 69, /* xmc0_5:1 */
182 72, /* xmc0_6:1 */
183 75, /* xmc0_7:1 */
184 78, /* xmc0_8:1 */
185 81, /* xmc0_9:1 */
186 84, /* xmc0_10:1 */
187 87, /* xmc0_11:1 */
188 90, /* xmc0_12:1 */
189 110, /* xmc1_0:1 */
190 113, /* xmc1_1:1 */
191 116, /* xmc1_2:1 */
192 119, /* xmc1_3:1 */
193 122, /* xmc1_4:1 */
194 125, /* xmc1_5:1 */
195 128, /* xmc1_6:1 */
196 131, /* xmc1_7:1 */
197 134, /* xmc1_8:1 */
198 137, /* xmc1_9:1 */
199 140, /* xmc1_10:1 */
200 143, /* xmc1_11:1 */
201 146, /* xmc1_12:1 */
202 166, /* xmc2_0:1 */
203 169, /* xmc2_1:1 */
204 172, /* xmc2_2:1 */
205 175, /* xmc2_3:1 */
206 178, /* xmc2_4:1 */
207 181, /* xmc2_5:1 */
208 184, /* xmc2_6:1 */
209 187, /* xmc2_7:1 */
210 190, /* xmc2_8:1 */
211 193, /* xmc2_9:1 */
212 196, /* xmc2_10:1 */
213 199, /* xmc2_11:1 */
214 202, /* xmc2_12:1 */
215 222, /* xmc3_0:1 */
216 225, /* xmc3_1:1 */
217 228, /* xmc3_2:1 */
218 231, /* xmc3_3:1 */
219 234, /* xmc3_4:1 */
220 237, /* xmc3_5:1 */
221 240, /* xmc3_6:1 */
222 243, /* xmc3_7:1 */
223 246, /* xmc3_8:1 */
224 249, /* xmc3_9:1 */
225 252, /* xmc3_10:1 */
226 255, /* xmc3_11:1 */
227 258, /* xmc3_12:1 */
228 5, /* LARc0:0 */
229 10, /* LARc1:1 */
230 15, /* LARc2:1 */
231 28, /* LARc5:1 */
232 32, /* LARc6:0 */
233 34, /* LARc7:1 */
234 35, /* LARc7:0 */
235 16, /* LARc2:0 */
236 20, /* LARc3:1 */
237 21, /* LARc3:0 */
238 25, /* LARc4:0 */
239 52, /* Xmaxc0:0 */
240 108, /* Xmaxc1:0 */
241 164, /* Xmaxc2:0 */
242 220, /* Xmaxc3:0 */
243 55, /* xmc0_0:0 */
244 58, /* xmc0_1:0 */
245 61, /* xmc0_2:0 */
246 64, /* xmc0_3:0 */
247 67, /* xmc0_4:0 */
248 70, /* xmc0_5:0 */
249 73, /* xmc0_6:0 */
250 76, /* xmc0_7:0 */
251 79, /* xmc0_8:0 */
252 82, /* xmc0_9:0 */
253 85, /* xmc0_10:0 */
254 88, /* xmc0_11:0 */
255 91, /* xmc0_12:0 */
256 111, /* xmc1_0:0 */
257 114, /* xmc1_1:0 */
258 117, /* xmc1_2:0 */
259 120, /* xmc1_3:0 */
260 123, /* xmc1_4:0 */
261 126, /* xmc1_5:0 */
262 129, /* xmc1_6:0 */
263 132, /* xmc1_7:0 */
264 135, /* xmc1_8:0 */
265 138, /* xmc1_9:0 */
266 141, /* xmc1_10:0 */
267 144, /* xmc1_11:0 */
268 147, /* xmc1_12:0 */
269 167, /* xmc2_0:0 */
270 170, /* xmc2_1:0 */
271 173, /* xmc2_2:0 */
272 176, /* xmc2_3:0 */
273 179, /* xmc2_4:0 */
274 182, /* xmc2_5:0 */
275 185, /* xmc2_6:0 */
276 188, /* xmc2_7:0 */
277 191, /* xmc2_8:0 */
278 194, /* xmc2_9:0 */
279 197, /* xmc2_10:0 */
280 200, /* xmc2_11:0 */
281 203, /* xmc2_12:0 */
282 223, /* xmc3_0:0 */
283 226, /* xmc3_1:0 */
284 229, /* xmc3_2:0 */
285 232, /* xmc3_3:0 */
286 235, /* xmc3_4:0 */
287 238, /* xmc3_5:0 */
288 241, /* xmc3_6:0 */
289 244, /* xmc3_7:0 */
290 247, /* xmc3_8:0 */
291 250, /* xmc3_9:0 */
292 253, /* xmc3_10:0 */
293 256, /* xmc3_11:0 */
294 259, /* xmc3_12:0 */
295 11, /* LARc1:0 */
296 29, /* LARc5:0 */
297};
Maxec8f1922016-05-31 14:50:21 +0200298
Mychaela N. Falconiaf86ec502023-05-10 18:18:42 +0000299/*
300 * Table 1 in section 6 of 3GPP TS 46.011 (substitution and muting of lost
301 * frames) specifies a silence frame in the form of GSM 06.10 parameters;
302 * the following const datum is this GSM 06.11 silence frame in GSM-FR
303 * RTP encoding.
304 */
305const uint8_t osmo_gsm611_silence_frame[GSM_FR_BYTES] = {
306 0xDA, 0xA7, 0xAA, 0xA5, 0x1A,
307 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
308 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
309 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
310 0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
311};
312
Mychaela N. Falconiaec650852023-04-16 01:34:35 +0000313static const uint16_t sid_code_word_bits[95] = {
314 /* bit numbers are relative to the RTP frame beginning,
315 * with signature bits included in the count. */
316 57, 58, 60, 61, 63, 64, 66, 67, 69, 70, 72, 73,
317 75, 76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91,
318 93, 94, 113, 114, 116, 117, 119, 120, 122, 123,
319 125, 126, 128, 129, 131, 132, 134, 135, 137,
320 138, 140, 141, 143, 144, 146, 147, 149, 150,
321 169, 170, 172, 173, 175, 176, 178, 179, 181,
322 182, 184, 185, 187, 188, 190, 191, 193, 194,
323 196, 197, 199, 200, 202, 203, 205, 206, 225,
324 226, 228, 229, 231, 232, 234, 235, 237, 240,
325 243, 246, 249, 252, 255, 258, 261
326};
327
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200328/*! Check whether RTP frame contains FR SID code word according to
Maxec8f1922016-05-31 14:50:21 +0200329 * TS 101 318 §5.1.2
330 * \param[in] rtp_payload Buffer with RTP payload
331 * \param[in] payload_len Length of payload
332 * \returns true if code word is found, false otherwise
333 */
Harald Welte6789ba32017-05-31 02:47:43 +0200334bool osmo_fr_check_sid(const uint8_t *rtp_payload, size_t payload_len)
Maxec8f1922016-05-31 14:50:21 +0200335{
336 struct bitvec bv;
Mychaela N. Falconiaec650852023-04-16 01:34:35 +0000337 uint16_t i;
Maxec8f1922016-05-31 14:50:21 +0200338
339 /* signature does not match Full Rate SID */
340 if ((rtp_payload[0] >> 4) != 0xD)
341 return false;
342
Harald Welte6789ba32017-05-31 02:47:43 +0200343 bv.data = (uint8_t *) rtp_payload;
Maxec8f1922016-05-31 14:50:21 +0200344 bv.data_len = payload_len;
345
Mychaela N. Falconiaec650852023-04-16 01:34:35 +0000346 /* code word is all 0 at given bits */
347 for (i = 0; i < ARRAY_SIZE(sid_code_word_bits); i++) {
348 if (bitvec_get_bit_pos(&bv, sid_code_word_bits[i]) != ZERO)
Maxec8f1922016-05-31 14:50:21 +0200349 return false;
Mychaela N. Falconiaec650852023-04-16 01:34:35 +0000350 }
Maxec8f1922016-05-31 14:50:21 +0200351
352 return true;
353}
Mychaela N. Falconiaec650852023-04-16 01:34:35 +0000354
355/*! Classify potentially-SID FR codec frame in RTP format according
356 * to the rules of GSM 06.31 §6.1.1
357 * \param[in] rtp_payload Buffer with RTP payload
358 * \returns enum osmo_gsm631_sid_class, with symbolic values
359 * OSMO_GSM631_SID_CLASS_SPEECH, OSMO_GSM631_SID_CLASS_INVALID or
360 * OSMO_GSM631_SID_CLASS_VALID corresponding to the 3 possible bit-counting
361 * classifications prescribed by the spec.
362 *
363 * Differences between the more familiar osmo_fr_check_sid() and the present
364 * function are:
365 *
366 * 1. osmo_fr_check_sid() returns true only if the SID frame is absolutely
367 * perfect, with all 95 bits of the SID code word zeroed. However, the
368 * rules of GSM 06.31 §6.1.1 allow up to one bit to be in error,
369 * and the frame is still accepted as valid SID.
370 *
371 * 2. The third possible state of invalid SID is not handled at all by the
372 * simpler osmo_fr_check_sid() function.
373 *
374 * 3. osmo_fr_check_sid() includes a check for 0xD RTP signature, and returns
375 * false if that signature nibble is wrong. That check is not included
376 * in the present version because there is no place for it in the
377 * ETSI-prescribed classification, it is neither speech nor SID. The
378 * assumption is that this function is used to classify the bit content
379 * of received codec frames, not their RTP encoding - the latter needs
380 * to be validated beforehand.
381 *
382 * Which function should one use? The answer depends on the specific
383 * circumstances, and needs to be addressed on a case-by-case basis.
384 */
385enum osmo_gsm631_sid_class osmo_fr_sid_classify(const uint8_t *rtp_payload)
386{
387 struct bitvec bv;
388 uint16_t i, n;
389
390 bv.data = (uint8_t *) rtp_payload;
391 bv.data_len = GSM_FR_BYTES;
392
393 /* count not-SID-matching bits per the spec */
394 n = 0;
395 for (i = 0; i < ARRAY_SIZE(sid_code_word_bits); i++) {
396 if (bitvec_get_bit_pos(&bv, sid_code_word_bits[i]) != ZERO)
397 n++;
398 if (n >= 16)
399 return OSMO_GSM631_SID_CLASS_SPEECH;
400 }
401 if (n >= 2)
402 return OSMO_GSM631_SID_CLASS_INVALID;
403 else
404 return OSMO_GSM631_SID_CLASS_VALID;
405}
Mychaela N. Falconia295636b2023-04-16 17:19:50 +0000406
Mychaela N. Falconia2974a232023-05-26 20:38:02 +0000407/*! Reset the SID field and the unused bits of a potentially corrupted,
408 * but still valid GSM-FR SID frame in RTP encoding to their pristine state.
409 * \param[in] rtp_payload Buffer with RTP payload - must be writable!
410 *
411 * Per GSM 06.12 section 5.2, a freshly minted SID frame carries 60 bits
412 * of comfort noise parameters (LARc and 4 times Xmaxc), while the remaining
413 * 200 bits are all zeros; the latter 200 all-0 bits further break down into
414 * 95 bits of SID field (checked by receivers to detect SID) and 105 unused
415 * bits which receivers are told to ignore. Network elements that receive
416 * SID frames from call leg A uplink and need to retransmit them on leg B
417 * downlink should "rejuvenate" received SID frames prior to retransmission;
418 * this function does the job.
419 */
420void osmo_fr_sid_reset(uint8_t *rtp_payload)
421{
422 uint8_t *p, sub;
423
424 p = rtp_payload + 5; /* skip magic+LARc */
425 for (sub = 0; sub < 4; sub++) {
426 *p++ = 0;
427 *p++ &= 0x1F; /* upper 5 bits of Xmaxc field */
428 *p++ &= 0x80; /* and the lsb spilling into the next byte */
429 *p++ = 0;
430 *p++ = 0;
431 *p++ = 0;
432 *p++ = 0;
433 }
434}
435
Mychaela N. Falconia295636b2023-04-16 17:19:50 +0000436/*! Preen potentially-SID FR codec frame in RTP format, ensuring that it is
437 * either a speech frame or a valid SID, and if the latter, making it a
438 * perfect, error-free SID frame.
439 * \param[in] rtp_payload Buffer with RTP payload - must be writable!
440 * \returns true if the frame is good, false otherwise
441 */
442bool osmo_fr_sid_preen(uint8_t *rtp_payload)
443{
444 enum osmo_gsm631_sid_class sidc;
Mychaela N. Falconia295636b2023-04-16 17:19:50 +0000445
446 sidc = osmo_fr_sid_classify(rtp_payload);
447 switch (sidc) {
448 case OSMO_GSM631_SID_CLASS_SPEECH:
449 return true;
450 case OSMO_GSM631_SID_CLASS_INVALID:
451 return false;
452 case OSMO_GSM631_SID_CLASS_VALID:
Mychaela N. Falconia2974a232023-05-26 20:38:02 +0000453 /* "Rejuvenate" this SID frame, correcting any errors */
454 osmo_fr_sid_reset(rtp_payload);
Mychaela N. Falconia295636b2023-04-16 17:19:50 +0000455 return true;
456 default:
457 /* There are only 3 possible SID classifications per GSM 06.31
458 * section 6.1.1, thus any other return value is a grave error
459 * in the code. */
460 OSMO_ASSERT(0);
461 }
462}