blob: 282781fdbc219c4ca788d3cf46712ecc245e8ff8 [file] [log] [blame]
Piotr Krysik9e2e8352018-02-27 12:16:25 +01001/*! \file gsm620.c
2 * GSM 06.20 - GSM HR codec. */
3/*
4 * (C) 2010 Sylvain Munaut <tnt@246tNt.com>
5 *
6 * All Rights Reserved
7 *
8 * SPDX-License-Identifier: GPL-2.0+
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 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 *
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
26#include <stdint.h>
27#include <stdbool.h>
28
29#include <osmocom/core/bitvec.h>
30#include <osmocom/core/utils.h>
31#include <osmocom/codec/codec.h>
32
33/* GSM HR unvoiced (mode=0) frames - subjective importance bit ordering */
34 /* This array encode mapping between GSM 05.03 Table 3a (bits
35 * ordering before channel coding on TCH) and GSM 06.20 Table B.1
36 * (bit ordering on A-bis */
37const uint16_t gsm620_unvoiced_bitorder[112] = {
38 3, /* R0:1 */
39 25, /* LPC 3:7 */
40 52, /* GSP 0-1:2 */
41 71, /* GSP 0-2:2 */
42 90, /* GSP 0-3:2 */
43 109, /* GSP 0-4:2 */
44 15, /* LPC 1:0 */
45 19, /* LPC 2:5 */
46 20, /* LPC 2:4 */
47 21, /* LPC 2:3 */
48 22, /* LPC 2:2 */
49 23, /* LPC 2:1 */
50 26, /* LPC 3:6 */
51 27, /* LPC 3:5 */
52 28, /* LPC 3:4 */
53 29, /* LPC 3:3 */
54 30, /* LPC 3:2 */
55 31, /* LPC 3:1 */
56 61, /* Code 1-2:0 */
57 62, /* Code 2-2:6 */
58 63, /* Code 2-2:5 */
59 64, /* Code 2-2:4 */
60 65, /* Code 2-2:3 */
61 66, /* Code 2-2:2 */
62 67, /* Code 2-2:1 */
63 68, /* Code 2-2:0 */
64 74, /* Code 1-3:6 */
65 75, /* Code 1-3:5 */
66 76, /* Code 1-3:4 */
67 77, /* Code 1-3:3 */
68 78, /* Code 1-3:2 */
69 79, /* Code 1-3:1 */
70 80, /* Code 1-3:0 */
71 81, /* Code 2-3:6 */
72 82, /* Code 2-3:5 */
73 83, /* Code 2-3:4 */
74 84, /* Code 2-3:3 */
75 32, /* LPC 3:0 */
76 4, /* R0:0 */
77 33, /* INT-LPC:0 */
78 60, /* Code 1-2:1 */
79 59, /* Code 1-2:2 */
80 58, /* Code 1-2:3 */
81 57, /* Code 1-2:4 */
82 56, /* Code 1-2:5 */
83 55, /* Code 1-2:6 */
84 49, /* Code 2-1:0 */
85 48, /* Code 2-1:1 */
86 47, /* Code 2-1:2 */
87 46, /* Code 2-1:3 */
88 45, /* Code 2-1:4 */
89 44, /* Code 2-1:5 */
90 43, /* Code 2-1:6 */
91 42, /* Code 1-1:0 */
92 41, /* Code 1-1:1 */
93 40, /* Code 1-1:2 */
94 39, /* Code 1-1:3 */
95 38, /* Code 1-1:4 */
96 37, /* Code 1-1:5 */
97 36, /* Code 1-1:6 */
98 111, /* GSP 0-4:0 */
99 92, /* GSP 0-3:0 */
100 73, /* GSP 0-2:0 */
101 54, /* GSP 0-1:0 */
102 24, /* LPC 2:0 */
103 110, /* GSP 0-4:1 */
104 91, /* GSP 0-3:1 */
105 72, /* GSP 0-2:1 */
106 53, /* GSP 0-1:1 */
107 14, /* LPC 1:1 */
108 13, /* LPC 1:2 */
109 12, /* LPC 1:3 */
110 11, /* LPC 1:4 */
111 10, /* LPC 1:5 */
112 108, /* GSP 0-4:3 */
113 89, /* GSP 0-3:3 */
114 70, /* GSP 0-2:3 */
115 51, /* GSP 0-1:3 */
116 16, /* LPC 2:8 */
117 17, /* LPC 2:7 */
118 18, /* LPC 2:6 */
119 107, /* GSP 0-4:4 */
120 88, /* GSP 0-3:4 */
121 69, /* GSP 0-2:4 */
122 50, /* GSP 0-1:4 */
123 9, /* LPC 1:6 */
124 8, /* LPC 1:7 */
125 7, /* LPC 1:8 */
126 6, /* LPC 1:9 */
127 2, /* R0:2 */
128 5, /* LPC 1:10 */
129 1, /* R0:3 */
130 0, /* R0:4 */
131 35, /* Mode:0 */
132 34, /* Mode:1 */
133 106, /* Code 2-4:0 */
134 105, /* Code 2-4:1 */
135 104, /* Code 2-4:2 */
136 103, /* Code 2-4:3 */
137 102, /* Code 2-4:4 */
138 101, /* Code 2-4:5 */
139 100, /* Code 2-4:6 */
140 99, /* Code 1-4:0 */
141 98, /* Code 1-4:1 */
142 97, /* Code 1-4:2 */
143 96, /* Code 1-4:3 */
144 95, /* Code 1-4:4 */
145 94, /* Code 1-4:5 */
146 93, /* Code 1-4:6 */
147 87, /* Code 2-3:0 */
148 86, /* Code 2-3:1 */
149 85, /* Code 2-3:2 */
150};
151
152/* GSM HR voiced (mode=1,2,3) frames - subjective importance bit ordering */
153 /* This array encode mapping between GSM 05.03 Table 3b (bits
154 * ordering before channel coding on TCH) and GSM 06.20 Table B.2
155 * (bit ordering on A-bis */
156const uint16_t gsm620_voiced_bitorder[112] = {
157 13, /* LPC 1:2 */
158 14, /* LPC 1:1 */
159 18, /* LPC 2:6 */
160 19, /* LPC 2:5 */
161 20, /* LPC 2:4 */
162 53, /* GSP 0-1:4 */
163 71, /* GSP 0-2:4 */
164 89, /* GSP 0-3:4 */
165 107, /* GSP 0-4:4 */
166 54, /* GSP 0-1:3 */
167 72, /* GSP 0-2:3 */
168 90, /* GSP 0-3:3 */
169 108, /* GSP 0-4:3 */
170 55, /* GSP 0-1:2 */
171 73, /* GSP 0-2:2 */
172 91, /* GSP 0-3:2 */
173 109, /* GSP 0-4:2 */
174 44, /* Code 1:8 */
175 45, /* Code 1:7 */
176 46, /* Code 1:6 */
177 47, /* Code 1:5 */
178 48, /* Code 1:4 */
179 49, /* Code 1:3 */
180 50, /* Code 1:2 */
181 51, /* Code 1:1 */
182 52, /* Code 1:0 */
183 62, /* Code 2:8 */
184 63, /* Code 2:7 */
185 64, /* Code 2:6 */
186 65, /* Code 2:5 */
187 68, /* Code 2:2 */
188 69, /* Code 2:1 */
189 70, /* Code 2:0 */
190 80, /* Code 3:8 */
191 66, /* Code 2:4 */
192 67, /* Code 2:3 */
193 56, /* GSP 0-1:1 */
194 74, /* GSP 0-2:1 */
195 92, /* GSP 0-3:1 */
196 110, /* GSP 0-4:1 */
197 57, /* GSP 0-1:0 */
198 75, /* GSP 0-2:0 */
199 93, /* GSP 0-3:0 */
200 111, /* GSP 0-4:0 */
201 33, /* INT-LPC:0 */
202 24, /* LPC 2:0 */
203 32, /* LPC 3:0 */
204 97, /* LAG 4:0 */
205 31, /* LPC 3:1 */
206 23, /* LPC 2:1 */
207 96, /* LAG 4:1 */
208 79, /* LAG 3:0 */
209 61, /* LAG 2:0 */
210 43, /* LAG 1:0 */
211 95, /* LAG 4:2 */
212 78, /* LAG 3:1 */
213 60, /* LAG 2:1 */
214 42, /* LAG 1:1 */
215 30, /* LPC 3:2 */
216 29, /* LPC 3:3 */
217 28, /* LPC 3:4 */
218 22, /* LPC 2:2 */
219 27, /* LPC 3:5 */
220 26, /* LPC 3:6 */
221 21, /* LPC 2:3 */
222 4, /* R0:0 */
223 25, /* LPC 3:7 */
224 15, /* LPC 1:0 */
225 94, /* LAG 4:3 */
226 77, /* LAG 3:2 */
227 59, /* LAG 2:2 */
228 41, /* LAG 1:2 */
229 3, /* R0:1 */
230 76, /* LAG 3:3 */
231 58, /* LAG 2:3 */
232 40, /* LAG 1:3 */
233 39, /* LAG 1:4 */
234 17, /* LPC 2:7 */
235 16, /* LPC 2:8 */
236 12, /* LPC 1:3 */
237 11, /* LPC 1:4 */
238 10, /* LPC 1:5 */
239 9, /* LPC 1:6 */
240 2, /* R0:2 */
241 38, /* LAG 1:5 */
242 37, /* LAG 1:6 */
243 36, /* LAG 1:7 */
244 8, /* LPC 1:7 */
245 7, /* LPC 1:8 */
246 6, /* LPC 1:9 */
247 5, /* LPC 1:10 */
248 1, /* R0:3 */
249 0, /* R0:4 */
250 35, /* Mode:0 */
251 34, /* Mode:1 */
252 106, /* Code 4:0 */
253 105, /* Code 4:1 */
254 104, /* Code 4:2 */
255 103, /* Code 4:3 */
256 102, /* Code 4:4 */
257 101, /* Code 4:5 */
258 100, /* Code 4:6 */
259 99, /* Code 4:7 */
260 98, /* Code 4:8 */
261 88, /* Code 3:0 */
262 87, /* Code 3:1 */
263 86, /* Code 3:2 */
264 85, /* Code 3:3 */
265 84, /* Code 3:4 */
266 83, /* Code 3:5 */
267 82, /* Code 3:6 */
268 81, /* Code 3:7 */
269};
270
271static inline uint16_t mask(const uint8_t msb)
272{
273 const uint16_t m = (uint16_t)1 << (msb - 1);
274 return (m - 1) ^ m;
275}
276
277/*! Check whether RTP frame contains HR SID code word according to
278 * TS 101 318 ยง5.2.2
279 * \param[in] rtp_payload Buffer with RTP payload
280 * \param[in] payload_len Length of payload
281 * \returns true if code word is found, false otherwise
282 */
283bool osmo_hr_check_sid(const uint8_t *rtp_payload, size_t payload_len)
284{
285 uint8_t i, bits[] = { 1, 2, 8, 9, 5, 4, 9, 5, 4, 9, 5, 4, 9, 5 };
286 struct bitvec bv;
287 bv.data = (uint8_t *) rtp_payload;
288 bv.data_len = payload_len;
289 bv.cur_bit = 33;
290
291 /* code word is all 1 at given bits, numbered from 1, MODE is always 3 */
292 for (i = 0; i < ARRAY_SIZE(bits); i++)
293 if (bitvec_get_uint(&bv, bits[i]) != mask(bits[i]))
294 return false;
295
296 return true;
297}