comparison amrconv/cod2ietf.c @ 215:4c4649a5fec3

amrconv: new program amr-cod2ietf
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 21 Apr 2023 06:30:29 +0000
parents amrconv/cod-parse.c@0beafaa0623f
children
comparison
equal deleted inserted replaced
214:934cf92a1c45 215:4c4649a5fec3
1 /*
2 * This program converts an AMR-encoded speech recording from the .cod
3 * format used by 3GPP test sequences into the more common .amr format
4 * of IETF RFC 4867.
5 */
6
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <strings.h>
12 #include "amr_defs.h"
13
14 extern unsigned amr_bit_lengths[9];
15 extern const char amr_file_hdr[IETF_HDR_LEN];
16 extern const uint8_t extra_bytes_per_ft[9];
17
18 main(argc, argv)
19 char **argv;
20 {
21 char *infname, *outfname;
22 FILE *inf, *outf;
23 int big_endian;
24 unsigned frame_no, type, mode, outlen;
25 uint8_t input_bits[COD_FORMAT_NWORDS], frm_out[MAX_IF1_BYTES+1];
26 int rc;
27
28 if (argc == 3 && argv[1][0] != '-') {
29 big_endian = 0;
30 infname = argv[1];
31 outfname = argv[2];
32 } else if (argc == 4 && !strcmp(argv[1], "-b")) {
33 big_endian = 1;
34 infname = argv[2];
35 outfname = argv[3];
36 } else {
37 fprintf(stderr, "usage: %s [-b] input.cod output.amr\n",
38 argv[0]);
39 exit(1);
40 }
41 inf = fopen(infname, "r");
42 if (!inf) {
43 perror(infname);
44 exit(1);
45 }
46 outf = fopen(outfname, "w");
47 if (!outf) {
48 perror(outfname);
49 exit(1);
50 }
51 fwrite(amr_file_hdr, 1, IETF_HDR_LEN, outf);
52 for (frame_no = 0; ; frame_no++) {
53 rc = read_cod_bits(inf, big_endian, input_bits, infname);
54 if (!rc)
55 break;
56 type = input_bits[0];
57 mode = input_bits[245];
58 switch (type) {
59 case TX_SPEECH_GOOD:
60 if (mode > MR122) {
61 invalid_mode: fprintf(stderr,
62 "error in %s frame #%u: invalid mode\n",
63 infname, frame_no);
64 exit(1);
65 }
66 preen_frame_bits(input_bits+1, amr_bit_lengths[mode],
67 infname, frame_no);
68 frm_out[0] = (mode << 3) | 0x04;
69 amr_if1_pack(frm_out+1, input_bits+1, mode);
70 outlen = extra_bytes_per_ft[mode] + 1;
71 break;
72 case TX_SID_FIRST:
73 case TX_SID_UPDATE:
74 if (mode > MR122)
75 goto invalid_mode;
76 preen_frame_bits(input_bits+1, AMR_NBITS_SID, infname,
77 frame_no);
78 frm_out[0] = 0x44;
79 amr_if1_pack(frm_out+1, input_bits+1, MRDTX);
80 if (type == TX_SID_UPDATE)
81 frm_out[5] |= 0x10;
82 if (mode & 1)
83 frm_out[5] |= 0x08;
84 if (mode & 2)
85 frm_out[5] |= 0x04;
86 if (mode & 4)
87 frm_out[5] |= 0x02;
88 outlen = 6;
89 break;
90 case TX_NO_DATA:
91 frm_out[0] = 0x7C;
92 outlen = 1;
93 break;
94 default:
95 fprintf(stderr, "error in %s frame #%u: invalid type\n",
96 infname, frame_no);
97 exit(1);
98 }
99 fwrite(frm_out, 1, outlen, outf);
100 }
101 fclose(outf);
102 exit(0);
103 }