FreeCalypso > hg > gsm-codec-lib
changeset 215:4c4649a5fec3
amrconv: new program amr-cod2ietf
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 21 Apr 2023 06:30:29 +0000 |
parents | 934cf92a1c45 |
children | 9d59df9b0e4e |
files | .hgignore amrconv/Makefile amrconv/cod2ietf.c amrconv/if1_pack.c |
diffstat | 4 files changed, 200 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Apr 20 22:48:22 2023 +0000 +++ b/.hgignore Fri Apr 21 06:30:29 2023 +0000 @@ -3,6 +3,7 @@ \.[oa]$ ^amrconv/amr-cod-parse$ +^amrconv/amr-cod2ietf$ ^amrconv/amr-ietf-parse$ ^amrconv/gsm-amr2efr$ ^amrconv/gsm-efr2amr$
--- a/amrconv/Makefile Thu Apr 20 22:48:22 2023 +0000 +++ b/amrconv/Makefile Fri Apr 21 06:30:29 2023 +0000 @@ -1,6 +1,6 @@ CC= gcc CFLAGS= -O2 -PROGS= amr-cod-parse amr-ietf-parse gsm-amr2efr gsm-efr2amr +PROGS= amr-cod-parse amr-cod2ietf amr-ietf-parse gsm-amr2efr gsm-efr2amr LIBTEST=../libtest/libtest.a INSTBIN=/opt/freecalypso/bin @@ -11,11 +11,17 @@ IETF_PARSE_OBJS=amr122bits.o amr_bits.o amr_common_tbl.o bitmanip.o \ ietf-parse.o ietf_common.o if1_unpack.o param_asm.o param_dump.o +COD2IETF_OBJS= amr122bits.o amr_bits.o amr_common_tbl.o bitmanip.o cod-read.o \ + cod2ietf.o ietf_common.o if1_pack.o + all: ${PROGS} amr-cod-parse: ${COD_PARSE_OBJS} ${CC} ${CFLAGS} -o $@ ${COD_PARSE_OBJS} +amr-cod2ietf: ${COD2IETF_OBJS} + ${CC} ${CFLAGS} -o $@ ${COD2IETF_OBJS} + amr-ietf-parse: ${IETF_PARSE_OBJS} ${CC} ${CFLAGS} -o $@ ${IETF_PARSE_OBJS}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrconv/cod2ietf.c Fri Apr 21 06:30:29 2023 +0000 @@ -0,0 +1,103 @@ +/* + * This program converts an AMR-encoded speech recording from the .cod + * format used by 3GPP test sequences into the more common .amr format + * of IETF RFC 4867. + */ + +#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]; + +main(argc, argv) + char **argv; +{ + char *infname, *outfname; + FILE *inf, *outf; + int big_endian; + unsigned frame_no, type, mode, outlen; + uint8_t input_bits[COD_FORMAT_NWORDS], frm_out[MAX_IF1_BYTES+1]; + int rc; + + if (argc == 3 && argv[1][0] != '-') { + big_endian = 0; + infname = argv[1]; + outfname = argv[2]; + } else if (argc == 4 && !strcmp(argv[1], "-b")) { + big_endian = 1; + infname = argv[2]; + outfname = argv[3]; + } else { + fprintf(stderr, "usage: %s [-b] input.cod output.amr\n", + argv[0]); + exit(1); + } + inf = fopen(infname, "r"); + if (!inf) { + perror(infname); + exit(1); + } + outf = fopen(outfname, "w"); + if (!outf) { + perror(outfname); + exit(1); + } + fwrite(amr_file_hdr, 1, IETF_HDR_LEN, outf); + for (frame_no = 0; ; frame_no++) { + rc = read_cod_bits(inf, big_endian, input_bits, infname); + if (!rc) + break; + type = input_bits[0]; + mode = input_bits[245]; + switch (type) { + case TX_SPEECH_GOOD: + if (mode > MR122) { +invalid_mode: fprintf(stderr, + "error in %s frame #%u: invalid mode\n", + infname, frame_no); + exit(1); + } + preen_frame_bits(input_bits+1, amr_bit_lengths[mode], + infname, frame_no); + frm_out[0] = (mode << 3) | 0x04; + amr_if1_pack(frm_out+1, input_bits+1, mode); + outlen = extra_bytes_per_ft[mode] + 1; + break; + case TX_SID_FIRST: + case TX_SID_UPDATE: + if (mode > MR122) + goto invalid_mode; + preen_frame_bits(input_bits+1, AMR_NBITS_SID, infname, + frame_no); + frm_out[0] = 0x44; + amr_if1_pack(frm_out+1, input_bits+1, MRDTX); + if (type == TX_SID_UPDATE) + frm_out[5] |= 0x10; + if (mode & 1) + frm_out[5] |= 0x08; + if (mode & 2) + frm_out[5] |= 0x04; + if (mode & 4) + frm_out[5] |= 0x02; + outlen = 6; + break; + case TX_NO_DATA: + frm_out[0] = 0x7C; + outlen = 1; + break; + default: + fprintf(stderr, "error in %s frame #%u: invalid type\n", + infname, frame_no); + exit(1); + } + fwrite(frm_out, 1, outlen, outf); + } + fclose(outf); + exit(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amrconv/if1_pack.c Fri Apr 21 06:30:29 2023 +0000 @@ -0,0 +1,89 @@ +/* + * In this module we implement our function for packing AMR codec bits + * from an array containing them in the codec's natural bit order + * into the octet form of AMR IF1 and RFC 4867. + */ + +#include <stdint.h> +#include "amr_defs.h" + +extern const uint8_t amr_475_bit_order[95]; +extern const uint8_t amr_515_bit_order[103]; +extern const uint8_t amr_59_bit_order[118]; +extern const uint8_t amr_67_bit_order[134]; +extern const uint8_t amr_74_bit_order[148]; +extern const uint8_t amr_795_bit_order[159]; +extern const uint8_t amr_102_bit_order[204]; +extern const uint8_t amr_122_bit_order[244]; + +static void +pack_bits(if1_bytes, codec_bits, nbits, table) + uint8_t *if1_bytes, *codec_bits; + unsigned nbits; + const uint8_t *table; +{ + unsigned n, nb; + + for (n = 0; n < nbits; n++) { + if (table) + nb = table[n]; + else + nb = n; + msb_set_bit(if1_bytes, n, codec_bits[nb]); + } +} + +amr_if1_pack(if1_bytes, codec_bits, mode) + uint8_t *if1_bytes, *codec_bits; + unsigned mode; +{ + switch (mode) { + case MR475: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_475, + amr_475_bit_order); + if1_bytes[11] &= 0xFE; + return(0); + case MR515: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_515, + amr_515_bit_order); + if1_bytes[12] &= 0xFE; + return(0); + case MR59: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_59, + amr_59_bit_order); + if1_bytes[14] &= 0xFC; + return(0); + case MR67: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_67, + amr_67_bit_order); + if1_bytes[16] &= 0xFC; + return(0); + case MR74: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_74, + amr_74_bit_order); + if1_bytes[18] &= 0xF0; + return(0); + case MR795: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_795, + amr_795_bit_order); + if1_bytes[19] &= 0xFE; + return(0); + case MR102: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_102, + amr_102_bit_order); + if1_bytes[25] &= 0xF0; + return(0); + case MR122: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_122, + amr_122_bit_order); + if1_bytes[30] &= 0xF0; + return(0); + case MRDTX: + pack_bits(if1_bytes, codec_bits, AMR_NBITS_SID, + (const uint8_t *) 0); + if1_bytes[4] &= 0xE0; + return(0); + default: + return(-1); + } +}