comparison amrconv/ietf2cod.c @ 216:9d59df9b0e4e

amrconv: new program amr-ietf2cod
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 21 Apr 2023 21:28:02 +0000
parents amrconv/cod2ietf.c@4c4649a5fec3
children 1a7d659a952f
comparison
equal deleted inserted replaced
215:4c4649a5fec3 216:9d59df9b0e4e
1 /*
2 * This program converts an AMR-encoded speech recording from the common
3 * IETF RFC 4867 .amr format into the 3GPP test sequence .cod format.
4 */
5
6 #include <stdio.h>
7 #include <stdint.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <strings.h>
11 #include "amr_defs.h"
12
13 extern unsigned amr_bit_lengths[9];
14 extern const char amr_file_hdr[IETF_HDR_LEN];
15 extern const uint8_t extra_bytes_per_ft[9];
16
17 static void
18 bits2words(ser_bits, cod_words, nbits)
19 uint8_t *ser_bits;
20 uint16_t *cod_words;
21 unsigned nbits;
22 {
23 uint8_t *sp = ser_bits;
24 uint16_t *dp = cod_words;
25 unsigned n;
26
27 for (n = 0; n < nbits; n++)
28 *dp++ = *sp++;
29 while (n < MAX_SERIAL_SIZE)
30 *dp++ = 0;
31 }
32
33 main(argc, argv)
34 char **argv;
35 {
36 char *infname, *outfname;
37 FILE *inf, *outf;
38 uint8_t frm_in[MAX_IF1_BYTES];
39 unsigned frame_no, mode, qbit, sti, sid_mode;
40 uint8_t ser_bits[MAX_SERIAL_SIZE];
41 uint16_t cod_words[COD_FORMAT_NWORDS];
42 int rc;
43
44 if (argc != 3) {
45 fprintf(stderr, "usage: %s input.amr output.cod\n", argv[0]);
46 exit(1);
47 }
48 infname = argv[1];
49 outfname = argv[2];
50 inf = fopen(infname, "r");
51 if (!inf) {
52 perror(infname);
53 exit(1);
54 }
55 if (fread(frm_in, 1, IETF_HDR_LEN, inf) != IETF_HDR_LEN ||
56 bcmp(frm_in, amr_file_hdr, IETF_HDR_LEN)) {
57 fprintf(stderr, "error: %s is not in IETF AMR format\n",
58 infname);
59 exit(1);
60 }
61 outf = fopen(outfname, "w");
62 if (!outf) {
63 perror(outfname);
64 exit(1);
65 }
66 /* padding words which will never be filled */
67 bzero(cod_words + MAX_SERIAL_SIZE + 2, sizeof(uint16_t) * 4);
68 for (frame_no = 0; ; frame_no++) {
69 rc = getc(inf);
70 if (rc < 0)
71 break;
72 mode = (rc & 0x78) >> 3;
73 qbit = (rc & 4) >> 2;
74 if (mode == MODE_NO_DATA) {
75 cod_words[0] = TX_NO_DATA;
76 bzero(cod_words+1, sizeof(uint16_t) * MAX_SERIAL_SIZE);
77 cod_words[245] = 0xFFFF;
78 goto output;
79 }
80 if (mode > MRDTX) {
81 fprintf(stderr, "error in frame #%u: invalid FT=%u\n",
82 frame_no, mode);
83 exit(1);
84 }
85 rc = fread(frm_in, 1, extra_bytes_per_ft[mode], inf);
86 if (rc != extra_bytes_per_ft[mode]) {
87 fprintf(stderr,
88 "error: short read from %s on frame #%u\n",
89 infname, frame_no);
90 exit(1);
91 }
92 amr_if1_unpack(frm_in, ser_bits, mode);
93 if (mode == MRDTX) {
94 sti = (frm_in[4] & 0x10) >> 4;
95 sid_mode = 0;
96 if (frm_in[4] & 0x08)
97 sid_mode |= 1;
98 if (frm_in[4] & 0x04)
99 sid_mode |= 2;
100 if (frm_in[4] & 0x02)
101 sid_mode |= 4;
102 }
103 bits2words(ser_bits, cod_words + 1, amr_bit_lengths[mode]);
104 if (mode == MRDTX) {
105 if (qbit)
106 cod_words[0] = sti ? TX_SID_UPDATE
107 : TX_SID_FIRST;
108 else
109 cod_words[0] = TX_SID_BAD;
110 cod_words[245] = sid_mode;
111 } else {
112 cod_words[0] = qbit ? TX_SPEECH_GOOD : TX_SPEECH_BAD;
113 cod_words[245] = mode;
114 }
115 output: fwrite(cod_words, 2, COD_FORMAT_NWORDS, outf);
116 }
117 fclose(outf);
118 exit(0);
119 }