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 | * |
| 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> |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 27 | #include <stdbool.h> |
| 28 | |
| 29 | #include <osmocom/core/bitvec.h> |
| 30 | #include <osmocom/core/utils.h> |
Harald Welte | dee7172 | 2017-05-31 02:48:48 +0200 | [diff] [blame] | 31 | #include <osmocom/codec/codec.h> |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 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 */ |
Diego Elio Pettenò | 23431c7 | 2012-06-29 13:01:27 -0700 | [diff] [blame] | 37 | const uint16_t gsm620_unvoiced_bitorder[112] = { |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 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 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 45 | 19, /* LPC 2:5 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 46 | 20, /* LPC 2:4 */ |
| 47 | 21, /* LPC 2:3 */ |
| 48 | 22, /* LPC 2:2 */ |
| 49 | 23, /* LPC 2:1 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 50 | 26, /* LPC 3:6 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 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 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 56 | 61, /* Code 1-2:0 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 57 | 62, /* Code 2-2:6 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 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 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 64 | 74, /* Code 1-3:6 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 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 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 71 | 81, /* Code 2-3:6 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 72 | 82, /* Code 2-3:5 */ |
| 73 | 83, /* Code 2-3:4 */ |
| 74 | 84, /* Code 2-3:3 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 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 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 116 | 16, /* LPC 2:8 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 117 | 17, /* LPC 2:7 */ |
| 118 | 18, /* LPC 2:6 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 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 */ |
Diego Elio Pettenò | 23431c7 | 2012-06-29 13:01:27 -0700 | [diff] [blame] | 156 | const uint16_t gsm620_voiced_bitorder[112] = { |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 157 | 13, /* LPC 1:2 */ |
| 158 | 14, /* LPC 1:1 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 159 | 18, /* LPC 2:6 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 160 | 19, /* LPC 2:5 */ |
| 161 | 20, /* LPC 2:4 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 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 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 174 | 44, /* Code 1:8 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 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 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 183 | 62, /* Code 2:8 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 184 | 63, /* Code 2:7 */ |
| 185 | 64, /* Code 2:6 */ |
| 186 | 65, /* Code 2:5 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 187 | 68, /* Code 2:2 */ |
Sylvain Munaut | ed8170a | 2013-03-01 16:35:46 +0100 | [diff] [blame] | 188 | 69, /* Code 2:1 */ |
| 189 | 70, /* Code 2:0 */ |
Sylvain Munaut | 1a4ea5b | 2010-10-08 15:09:16 +0200 | [diff] [blame] | 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 | }; |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 270 | |
| 271 | static 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 | |
Neels Hofmeyr | 87e4550 | 2017-06-20 00:17:59 +0200 | [diff] [blame] | 277 | /*! Check whether RTP frame contains HR SID code word according to |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 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 | */ |
Harald Welte | 6789ba3 | 2017-05-31 02:47:43 +0200 | [diff] [blame] | 283 | 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] | 284 | { |
| 285 | uint8_t i, bits[] = { 1, 2, 8, 9, 5, 4, 9, 5, 4, 9, 5, 4, 9, 5 }; |
| 286 | struct bitvec bv; |
Harald Welte | 6789ba3 | 2017-05-31 02:47:43 +0200 | [diff] [blame] | 287 | bv.data = (uint8_t *) rtp_payload; |
Max | ec8f192 | 2016-05-31 14:50:21 +0200 | [diff] [blame] | 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 | } |