FreeCalypso > hg > gsm-codec-lib
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 } |