changeset 104:9cc76853d291

TRAU-AMR-8k: implement MR67 speech decoding
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 20 Nov 2025 22:09:43 +0000
parents 4edffa52802d
children 699afc9ef063
files trau-decode/amr8-common.c
diffstat 1 files changed, 76 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/trau-decode/amr8-common.c	Thu Nov 20 20:51:40 2025 +0000
+++ b/trau-decode/amr8-common.c	Thu Nov 20 22:09:43 2025 +0000
@@ -259,16 +259,16 @@
 	ubit_t *c_bits, *d_bits;
 {
 	ubit_t crc_collect[34];
-	int crc1;
+	int crc_stat;
 
 	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)
+	crc_stat = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 34,
+					   d_bits + 51);
+	printf("    CRC %s\n", crc_stat ? "bad" : "good");
+	if (crc_stat)
 		saved_mode_valid = 0;
 	print_speech_params(d_bits, params_lsf_59_67_74);
 	print_speech_params(d_bits + 26, params_59_sf13);
@@ -292,7 +292,7 @@
 	unsigned c4_5 = bits_to_num(c_bits + 3, 2);
 	unsigned mode;
 
-	printf("  Speech: RIF=%u, %s\n", rif, fclass_names[c4_5]);
+	printf("  Speech: RIF=%u FC=%s\n", rif, fclass_names[c4_5]);
 	if (rif) {
 		printf("  CMR=%u\n", c1_3 - 3);
 		if (!saved_mode_valid) {
@@ -383,10 +383,79 @@
 }
 
 static void
+decode_6k7_7k4_common(c_bits, d_bits, mode, cmr_offset)
+	ubit_t *c_bits, *d_bits;
+	char *mode;
+{
+	unsigned c1_3 = bits_to_num(c_bits, 3);
+	unsigned rif, fc, cmr_code;
+
+	printf("  %s speech, C1-C3: %u%u%u\n", mode, c_bits[0], c_bits[1],
+		c_bits[2]);
+	switch (c1_3) {
+	case 0:
+		rif = 0;
+		fc = 1;
+		break;
+	case 1:
+		rif = 0;
+		fc = 3;
+		break;
+	case 2:
+		rif = 1;
+		fc = 1;
+		cmr_code = bits_to_num(d_bits + cmr_offset, 3);
+		break;
+	default:
+		rif = 1;
+		fc = 3;
+		cmr_code = c1_3;
+	}
+	printf("  RIF=%u FC=%s\n", rif, fclass_names[fc]);
+	if (rif) {
+		if (cmr_code >= 3)
+			printf("  CMR=%u\n", cmr_code - 3);
+		else
+			puts("  CMR code in data bits is invalid");
+	}
+}
+
+static void
 handle_amr8_6k7(frame_bits)
 	ubit_t *frame_bits;
 {
-	puts("  TRAU-AMR-8k MR67 format, decoding to be implemented");
+	ubit_t *c_bits = frame_bits + 17;
+	ubit_t d_bits[137], crc_collect[35];
+	int crc_stat;
+
+	bcopy(frame_bits + 9, d_bits, 7);
+	bcopy(frame_bits + 20, d_bits + 7, 4);
+	bcopy(frame_bits + 25, d_bits + 11, 7);
+	bcopy(frame_bits + 33, d_bits + 18, 7);
+	bcopy(frame_bits + 41, d_bits + 25, 7);
+	bcopy(frame_bits + 49, d_bits + 32, 15);
+	bcopy(frame_bits + 65, d_bits + 47, 15);
+	bcopy(frame_bits + 81, d_bits + 62, 15);
+	bcopy(frame_bits + 97, d_bits + 77, 15);
+	bcopy(frame_bits + 113, d_bits + 92, 15);
+	bcopy(frame_bits + 129, d_bits + 107, 15);
+	bcopy(frame_bits + 145, d_bits + 122, 15);
+
+	decode_6k7_7k4_common(c_bits, d_bits, "MR67", 0);
+	bcopy(c_bits, crc_collect, 3);
+	bcopy(d_bits, crc_collect + 3, 17);
+	crc_collect[20] = d_bits[19];
+	crc_collect[21] = d_bits[23];
+	bcopy(d_bits + 26, crc_collect + 22, 8);
+	bcopy(d_bits + 48, crc_collect + 30, 5);
+	crc_stat = osmo_crc8gen_check_bits(&gsm0860_amr_crc3, crc_collect, 35,
+					   d_bits + 55);
+	printf("  CRC %s\n", crc_stat ? "bad" : "good");
+	print_speech_params(d_bits, params_lsf_59_67_74);
+	print_speech_params(d_bits + 26, params_67_sf13);
+	print_speech_params(d_bits + 58, params_67_sf24);
+	print_speech_params(d_bits + 83, params_67_sf13);
+	print_speech_params(d_bits + 112, params_67_sf24);
 	saved_mode_valid = 0;
 }