FreeCalypso > hg > gsm-codec-lib
diff amrconv/ietf-parse.c @ 214:934cf92a1c45
amrconv: new program amr-ietf-parse
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 20 Apr 2023 22:48:22 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrconv/ietf-parse.c Thu Apr 20 22:48:22 2023 +0000 @@ -0,0 +1,83 @@ +/* + * This program reads an AMR recording in IETF RFC 4867 format and parses it + * into a human-readable form. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "amr_defs.h" + +extern char *amr_mode_names[16]; +extern const char amr_file_hdr[IETF_HDR_LEN]; +extern const uint8_t extra_bytes_per_ft[9]; + +main(argc, argv) + char **argv; +{ + char *infname; + FILE *inf; + uint8_t frm_in[MAX_IF1_BYTES]; + unsigned frame_no, mode, qbit, sti, sid_mode; + uint8_t ser_bits[MAX_SERIAL_SIZE]; + uint16_t params[MAX_PRM_SIZE]; + int rc; + + if (argc != 2) { + fprintf(stderr, "usage: %s amr_file\n", argv[0]); + exit(1); + } + infname = argv[1]; + inf = fopen(infname, "r"); + if (!inf) { + perror(infname); + exit(1); + } + if (fread(frm_in, 1, IETF_HDR_LEN, inf) != IETF_HDR_LEN || + bcmp(frm_in, amr_file_hdr, IETF_HDR_LEN)) { + fprintf(stderr, "error: %s is not in IETF AMR format\n", + infname); + exit(1); + } + for (frame_no = 0; ; frame_no++) { + rc = getc(inf); + if (rc < 0) + break; + mode = (rc & 0x78) >> 3; + qbit = (rc & 4) >> 2; + printf("#%u: FT=%u (%s) Q=%u\n", frame_no, mode, + amr_mode_names[mode], qbit); + if (mode == MODE_NO_DATA) + continue; + if (mode > MRDTX) { + fprintf(stderr, "error in frame #%u: invalid FT=%u\n", + frame_no, mode); + exit(1); + } + rc = fread(frm_in, 1, extra_bytes_per_ft[mode], inf); + if (rc != extra_bytes_per_ft[mode]) { + fprintf(stderr, + "error: short read from %s on frame #%u\n", + infname, frame_no); + exit(1); + } + amr_if1_unpack(frm_in, ser_bits, mode); + reassemble_amr_params(ser_bits, params, mode); + dump_amr_params(params, mode); + if (mode == MRDTX) { + sti = (frm_in[4] & 0x10) >> 4; + sid_mode = 0; + if (frm_in[4] & 0x08) + sid_mode |= 1; + if (frm_in[4] & 0x04) + sid_mode |= 2; + if (frm_in[4] & 0x02) + sid_mode |= 4; + printf(" SID_%s Mode=%u\n", sti ? "UPDATE" : "FIRST", + sid_mode); + } + } + exit(0); +}