FreeCalypso > hg > gsm-codec-lib
changeset 216:9d59df9b0e4e
amrconv: new program amr-ietf2cod
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 21 Apr 2023 21:28:02 +0000 |
parents | 4c4649a5fec3 |
children | 1a7d659a952f |
files | .hgignore amrconv/Makefile amrconv/ietf2cod.c |
diffstat | 3 files changed, 127 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Fri Apr 21 06:30:29 2023 +0000 +++ b/.hgignore Fri Apr 21 21:28:02 2023 +0000 @@ -5,6 +5,7 @@ ^amrconv/amr-cod-parse$ ^amrconv/amr-cod2ietf$ ^amrconv/amr-ietf-parse$ +^amrconv/amr-ietf2cod$ ^amrconv/gsm-amr2efr$ ^amrconv/gsm-efr2amr$
--- a/amrconv/Makefile Fri Apr 21 06:30:29 2023 +0000 +++ b/amrconv/Makefile Fri Apr 21 21:28:02 2023 +0000 @@ -1,6 +1,7 @@ CC= gcc CFLAGS= -O2 -PROGS= amr-cod-parse amr-cod2ietf amr-ietf-parse gsm-amr2efr gsm-efr2amr +PROGS= amr-cod-parse amr-cod2ietf amr-ietf-parse amr-ietf2cod gsm-amr2efr \ + gsm-efr2amr LIBTEST=../libtest/libtest.a INSTBIN=/opt/freecalypso/bin @@ -13,6 +14,8 @@ COD2IETF_OBJS= amr122bits.o amr_bits.o amr_common_tbl.o bitmanip.o cod-read.o \ cod2ietf.o ietf_common.o if1_pack.o +IETF2COD_OBJS= amr122bits.o amr_bits.o amr_common_tbl.o bitmanip.o ietf2cod.o \ + ietf_common.o if1_unpack.o all: ${PROGS} @@ -25,6 +28,9 @@ amr-ietf-parse: ${IETF_PARSE_OBJS} ${CC} ${CFLAGS} -o $@ ${IETF_PARSE_OBJS} +amr-ietf2cod: ${IETF2COD_OBJS} + ${CC} ${CFLAGS} -o $@ ${IETF2COD_OBJS} + gsm-amr2efr: ${AMR2EFR_OBJS} ${CC} ${CFLAGS} -o $@ ${AMR2EFR_OBJS}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrconv/ietf2cod.c Fri Apr 21 21:28:02 2023 +0000 @@ -0,0 +1,119 @@ +/* + * This program converts an AMR-encoded speech recording from the common + * IETF RFC 4867 .amr format into the 3GPP test sequence .cod format. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "amr_defs.h" + +extern unsigned amr_bit_lengths[9]; +extern const char amr_file_hdr[IETF_HDR_LEN]; +extern const uint8_t extra_bytes_per_ft[9]; + +static void +bits2words(ser_bits, cod_words, nbits) + uint8_t *ser_bits; + uint16_t *cod_words; + unsigned nbits; +{ + uint8_t *sp = ser_bits; + uint16_t *dp = cod_words; + unsigned n; + + for (n = 0; n < nbits; n++) + *dp++ = *sp++; + while (n < MAX_SERIAL_SIZE) + *dp++ = 0; +} + +main(argc, argv) + char **argv; +{ + char *infname, *outfname; + FILE *inf, *outf; + uint8_t frm_in[MAX_IF1_BYTES]; + unsigned frame_no, mode, qbit, sti, sid_mode; + uint8_t ser_bits[MAX_SERIAL_SIZE]; + uint16_t cod_words[COD_FORMAT_NWORDS]; + int rc; + + if (argc != 3) { + fprintf(stderr, "usage: %s input.amr output.cod\n", argv[0]); + exit(1); + } + infname = argv[1]; + outfname = argv[2]; + 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); + } + outf = fopen(outfname, "w"); + if (!outf) { + perror(outfname); + exit(1); + } + /* padding words which will never be filled */ + bzero(cod_words + MAX_SERIAL_SIZE + 2, sizeof(uint16_t) * 4); + for (frame_no = 0; ; frame_no++) { + rc = getc(inf); + if (rc < 0) + break; + mode = (rc & 0x78) >> 3; + qbit = (rc & 4) >> 2; + if (mode == MODE_NO_DATA) { + cod_words[0] = TX_NO_DATA; + bzero(cod_words+1, sizeof(uint16_t) * MAX_SERIAL_SIZE); + cod_words[245] = 0xFFFF; + goto output; + } + 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); + 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; + } + bits2words(ser_bits, cod_words + 1, amr_bit_lengths[mode]); + if (mode == MRDTX) { + if (qbit) + cod_words[0] = sti ? TX_SID_UPDATE + : TX_SID_FIRST; + else + cod_words[0] = TX_SID_BAD; + cod_words[245] = sid_mode; + } else { + cod_words[0] = qbit ? TX_SPEECH_GOOD : TX_SPEECH_BAD; + cod_words[245] = mode; + } +output: fwrite(cod_words, 2, COD_FORMAT_NWORDS, outf); + } + fclose(outf); + exit(0); +}