FreeCalypso > hg > gsm-net-reveng
changeset 106:028307356ba9
trau-decode: new program trau-amr8-dump
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 21 Nov 2025 06:37:46 +0000 |
| parents | 699afc9ef063 |
| children | c6ffb176eaed |
| files | .hgignore trau-decode/Makefile trau-decode/amr8-common.c trau-decode/amr8-readbin.c |
| diffstat | 4 files changed, 170 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Nov 20 22:28:45 2025 +0000 +++ b/.hgignore Fri Nov 21 06:37:46 2025 +0000 @@ -19,6 +19,7 @@ ^trau-decode/dump-1bit$ ^trau-decode/tfo-parse-fr16$ +^trau-decode/trau-amr8-dump$ ^trau-decode/trau-amr8-dump-hex$ ^trau-decode/trau-extr$ ^trau-decode/trau-hr-dump$
--- a/trau-decode/Makefile Thu Nov 20 22:28:45 2025 +0000 +++ b/trau-decode/Makefile Fri Nov 21 06:37:46 2025 +0000 @@ -1,7 +1,7 @@ CC= gcc CFLAGS= -O2 -PROGS= dump-1bit tfo-parse-fr16 trau-amr8-dump-hex trau-extr trau-hr-dump \ - trau-hr-dump-hex trau-parse trau-parse-hex trau-sync8 +PROGS= dump-1bit tfo-parse-fr16 trau-amr8-dump trau-amr8-dump-hex trau-extr \ + trau-hr-dump trau-hr-dump-hex trau-parse trau-parse-hex trau-sync8 FR_OBJS=parse-fr.o parse-fr-common.o parse-efr.o HR_OBJS=gsmhr_unpack.o hr-guts.o @@ -16,6 +16,9 @@ tfo-parse-fr16: crc8gen.o parse-tfo16.o ${FR_OBJS} ${CC} ${CFLAGS} -o $@ $^ -lgsmfr2 -lgsmefr +trau-amr8-dump: amr8-common.o amr8-readbin.o crc8gen.o + ${CC} ${CFLAGS} -o $@ $^ + trau-amr8-dump-hex: amr8-common.o amr8-readhex.o crc8gen.o ${CC} ${CFLAGS} -o $@ $^
--- a/trau-decode/amr8-common.c Thu Nov 20 22:28:45 2025 +0000 +++ b/trau-decode/amr8-common.c Fri Nov 21 06:37:46 2025 +0000 @@ -58,7 +58,7 @@ static const ubit_t bit8_0[8] = { 0, }; /*!< check sync pattern for AMR No_Speech + low bit rate */ -static bool is_amr_low(const ubit_t *bits) +bool is_amr_low(const ubit_t *bits) { int i; @@ -79,7 +79,7 @@ } /*!< check sync pattern for AMR 6.7kBit/s */ -static bool is_amr_67(const ubit_t *bits) +bool is_amr_67(const ubit_t *bits) { int i; @@ -104,7 +104,7 @@ } /*!< check sync pattern for AMR 7.4kBit/s */ -static bool is_amr_74(const ubit_t *bits) +bool is_amr_74(const ubit_t *bits) { if (bits[0] != 0 || bits[1] != 0 || bits[2] != 1) return false;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trau-decode/amr8-readbin.c Fri Nov 21 06:37:46 2025 +0000 @@ -0,0 +1,161 @@ +/* + * This program reads a 64 kbit/s timeslot recording file, examines one + * of the eight 8 kbit/s subslots (selected), looks for 3 possible sync + * patterns of TRAU-AMR-8k, and decodes whatever it finds. + */ + +#include <sys/types.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> + +static uint8_t *filebuf; +static unsigned total_size; +static int include_raw; + +static void +read_ts_file(filename, subslot_arg) + char *filename, *subslot_arg; +{ + FILE *inf; + struct stat st; + int subslot, right_shift; + unsigned n; + uint8_t *dp; + int b; + + inf = fopen(filename, "r"); + if (!inf) { + perror(filename); + exit(1); + } + fstat(fileno(inf), &st); + if (!S_ISREG(st.st_mode)) { + fprintf(stderr, "error: %s is not a regular file\n", filename); + exit(1); + } + total_size = st.st_size; + if (total_size < 160) { + fprintf(stderr, "error: %s is too short\n", filename); + exit(1); + } + filebuf = malloc(total_size); + if (!filebuf) { + perror("malloc of file size"); + exit(1); + } + subslot = atoi(subslot_arg); + if (subslot < 0 || subslot > 7) { + fprintf(stderr, "error: invalid subslot argument\n"); + exit(1); + } + right_shift = 7 - subslot; + dp = filebuf; + for (n = 0; n < total_size; n++) { + b = getc(inf); + if (b < 0) { + fprintf(stderr, + "error: getc() returned EOF contrary to st_size\n"); + exit(1); + } + *dp++ = (b >> right_shift) & 1; + } + fclose(inf); +} + +static int +check_sync(pos) + unsigned pos; +{ + uint8_t *cand = filebuf + pos; + + if (is_amr_low(cand)) + return 1; + if (is_amr_67(cand)) + return 1; + if (is_amr_74(cand)) + return 1; + return 0; +} + +static void +dump_raw_frame(frame_bits) + uint8_t *frame_bits; +{ + uint8_t *sp = frame_bits; + unsigned n, m, d; + + for (n = 0; n < 40; n++) { + d = 0; + for (m = 0; m < 4; m++) { + d <<= 1; + d |= *sp++; + } + printf("%x", d); + } + putchar('\n'); +} + +static void +process_frame(pos) + unsigned pos; +{ + uint8_t *frame = filebuf + pos; + + printf("Frame at 0x%x:\n", pos); + if (include_raw) + dump_raw_frame(frame); + print_amr8_frame(frame); +} + +static void +process_filebuf() +{ + unsigned p, endp; + int sync = 0, match; + + endp = total_size - 160; + for (p = 0; p <= endp; ) { + match = check_sync(p); + if (match != sync) { + printf("# %s frame sync at file offset 0x%x\n", + match ? "Acquired" : "Lost", p); + } + if (match) { + process_frame(p); + p += 160; + } else + p++; + sync = match; + } +} + +main(argc, argv) + char **argv; +{ + extern int optind; + int c; + + while ((c = getopt(argc, argv, "r")) != EOF) { + switch (c) { + case 'r': + include_raw = 1; + continue; + default: + usage: + fprintf(stderr, "usage: %s [-r] binfile subslot\n", + argv[0]); + exit(1); + } + } + if (argc != optind + 2) + goto usage; + read_ts_file(argv[optind], argv[optind + 1]); + process_filebuf(); + exit(0); +}
