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