FreeCalypso > hg > gsm-net-reveng
changeset 103:4edffa52802d
TRAU-AMR-8k: implement low speech decoding
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Thu, 20 Nov 2025 20:51:40 +0000 |
| parents | b59a61446c34 |
| children | 9cc76853d291 |
| files | trau-decode/amr8-common.c |
| diffstat | 1 files changed, 134 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/trau-decode/amr8-common.c Thu Nov 20 19:18:26 2025 +0000 +++ b/trau-decode/amr8-common.c Thu Nov 20 20:51:40 2025 +0000 @@ -34,7 +34,7 @@ "Sid_Bad", "Sid_Update", "Onset", "Sid_First" }; -static const uint8_t params_lsf_475_515[] = {8, 8, 7, 0}; +static const uint8_t params_lsf_475_515[] = {8, 8, 7, 0}; static const uint8_t params_lsf_59_67_74[] = {8, 9, 9, 0}; static const uint8_t params_475_sf1[] = {8, 7, 2, 8, 0}; @@ -179,15 +179,135 @@ } static void +decode_mode_0(c_bits, d_bits) + ubit_t *c_bits, *d_bits; +{ + ubit_t crc_collect[36]; + int crc1, crc2, crc3, crc4; + + bcopy(c_bits, crc_collect, 5); + bcopy(d_bits + 3, crc_collect + 5, 16); + bcopy(d_bits + 20, crc_collect + 21, 2); + bcopy(d_bits + 23, crc_collect + 23, 9); + bcopy(d_bits + 47, crc_collect + 32, 4); + crc1 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 36, + d_bits + 51); + crc2 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, d_bits + 54, 7, + d_bits + 72); + bcopy(d_bits + 75, crc_collect, 2); + bcopy(d_bits + 92, crc_collect + 2, 4); + crc3 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 6, + d_bits + 96); + crc4 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, d_bits + 99, 2, + d_bits + 112); + printf(" CRC %s %s %s %s\n", + crc1 ? "bad" : "good", crc2 ? "bad" : "good", + crc3 ? "bad" : "good", crc4 ? "bad" : "good"); + if (crc1) + saved_mode_valid = 0; + print_speech_params(d_bits + 3, params_lsf_475_515); + print_speech_params(d_bits + 26, params_475_sf1); + print_speech_params(d_bits + 59, params_475_sf24); + print_speech_params(d_bits + 75, params_475_sf3); + print_speech_params(d_bits + 99, params_475_sf24); + check_spare_bits(d_bits, 3, "D1..D3"); + check_spare_bits(d_bits + 115, 126 - 115, "D116..D126"); +} + +static void +decode_mode_1(c_bits, d_bits) + ubit_t *c_bits, *d_bits; +{ + ubit_t crc_collect[37]; + int crc1, crc2, crc3, crc4; + + bcopy(c_bits, crc_collect, 5); + bcopy(d_bits + 5, crc_collect + 5, 16); + bcopy(d_bits + 23, crc_collect + 21, 11); + bcopy(d_bits + 46, crc_collect + 32, 5); + crc1 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 37, + d_bits + 51); + bcopy(d_bits + 54, crc_collect, 7); + bcopy(d_bits + 73, crc_collect + 7, 5); + crc2 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 12, + d_bits + 78); + bcopy(d_bits + 81, crc_collect, 2); + bcopy(d_bits + 95, crc_collect + 2, 5); + crc3 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 7, + d_bits + 100); + bcopy(d_bits + 103, crc_collect, 2); + bcopy(d_bits + 117, crc_collect + 2, 5); + crc4 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 7, + d_bits + 122); + printf(" CRC %s %s %s %s\n", + crc1 ? "bad" : "good", crc2 ? "bad" : "good", + crc3 ? "bad" : "good", crc4 ? "bad" : "good"); + if (crc1) + saved_mode_valid = 0; + print_speech_params(d_bits + 5, params_lsf_475_515); + print_speech_params(d_bits + 28, params_515_sf1); + print_speech_params(d_bits + 59, params_515_sf234); + print_speech_params(d_bits + 81, params_515_sf234); + print_speech_params(d_bits + 103, params_515_sf234); + check_spare_bits(d_bits, 5, "D1..D5"); + if (!d_bits[125]) + puts(" Bit D126 is 0 (expected 1)"); +} + +static void +decode_mode_2(c_bits, d_bits) + ubit_t *c_bits, *d_bits; +{ + ubit_t crc_collect[34]; + int crc1; + + bcopy(c_bits, crc_collect, 5); + bcopy(d_bits, crc_collect + 5, 17); + bcopy(d_bits + 26, crc_collect + 22, 8); + bcopy(d_bits + 47, crc_collect + 30, 4); + crc1 = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 34, + d_bits + 51); + printf(" CRC %s\n", crc1 ? "bad" : "good"); + if (crc1) + saved_mode_valid = 0; + print_speech_params(d_bits, params_lsf_59_67_74); + print_speech_params(d_bits + 26, params_59_sf13); + print_speech_params(d_bits + 59, params_59_sf24); + print_speech_params(d_bits + 80, params_59_sf13); + print_speech_params(d_bits + 105, params_59_sf24); +} + +static void (*per_mode_decode[3])() = { + decode_mode_0, + decode_mode_1, + decode_mode_2 +}; + +static void decode_speech_frame(c_bits, d_bits) ubit_t *c_bits, *d_bits; { unsigned c1_3 = bits_to_num(c_bits, 3); unsigned rif = (c1_3 >= 3); unsigned c4_5 = bits_to_num(c_bits + 3, 2); + unsigned mode; printf(" Speech: RIF=%u, %s\n", rif, fclass_names[c4_5]); - /* to be continued */ + if (rif) { + printf(" CMR=%u\n", c1_3 - 3); + if (!saved_mode_valid) { + puts(" Mode unknown, cannot decode"); + return; + } + mode = saved_mode; + saved_mode_valid = 0; + } else { + mode = c1_3; + saved_mode = mode; + saved_mode_valid = 1; + } + printf(" Decoding per speech mode %u\n", mode); + per_mode_decode[mode](c_bits, d_bits); } static void @@ -195,16 +315,22 @@ ubit_t *c_bits, *d_bits; { ubit_t crc_collect[5 + 51]; + unsigned cmi, cmr; int crc_stat; printf(" No_Speech: RIF=%u TA=%u UFE/DFE=%u\n", c_bits[2], bits_to_num(d_bits, 6), d_bits[6]); + cmi = bits_to_num(d_bits + 10, 3); + cmr = bits_to_num(d_bits + 13, 3); printf(" No_Spch_Class=%u%u%u (%s) CMI=%u CMR=%u\n", d_bits[7], d_bits[8], d_bits[9], - nospch_class_names[bits_to_num(d_bits + 7, 3)], - bits_to_num(d_bits + 10, 3), bits_to_num(d_bits + 13, 3)); - saved_mode = bits_to_num(d_bits + 7, 3); - saved_mode_valid = 1; + nospch_class_names[bits_to_num(d_bits + 7, 3)], cmi, cmr); + if (cmi <= 2) { + saved_mode = cmi; + saved_mode_valid = 1; + } else { + saved_mode_valid = 0; + } bcopy(c_bits, crc_collect, 5); bcopy(d_bits, crc_collect + 5, 51); crc_stat = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, @@ -261,8 +387,7 @@ ubit_t *frame_bits; { puts(" TRAU-AMR-8k MR67 format, decoding to be implemented"); - saved_mode = 3; - saved_mode_valid = 1; + saved_mode_valid = 0; } static void @@ -270,8 +395,7 @@ ubit_t *frame_bits; { puts(" TRAU-AMR-8k MR74 format, decoding to be implemented"); - saved_mode = 4; - saved_mode_valid = 1; + saved_mode_valid = 0; } void
