annotate amrconv/ietf2cod.c @ 481:cc0c244bd233

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