FreeCalypso > hg > gsm-codec-lib
annotate amrconv/ietf2cod.c @ 267:65d3304502bd
libgsmfr2: integrate long_term.c from libgsm
| author | Mychaela Falconia <falcon@freecalypso.org> | 
|---|---|
| date | Sun, 14 Apr 2024 01:01:19 +0000 | 
| parents | 1a7d659a952f | 
| children | 
| 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: 
215diff
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: 
215diff
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: 
148diff
changeset | 11 #include "amr_defs.h" | 
| 
78d1a6513393
amrconv: new program amr-cod-parse
 Mychaela Falconia <falcon@freecalypso.org> parents: 
148diff
changeset | 12 | 
| 
78d1a6513393
amrconv: new program amr-cod-parse
 Mychaela Falconia <falcon@freecalypso.org> parents: 
148diff
changeset | 13 extern unsigned amr_bit_lengths[9]; | 
| 215 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 14 extern const char amr_file_hdr[IETF_HDR_LEN]; | 
| 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
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: 
215diff
changeset | 17 static void | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 18 bits2words(ser_bits, cod_words, nbits) | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 19 uint8_t *ser_bits; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 20 uint16_t *cod_words; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 21 unsigned nbits; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 22 { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 23 uint8_t *sp = ser_bits; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 24 uint16_t *dp = cod_words; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 25 unsigned n; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 26 | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 27 for (n = 0; n < nbits; n++) | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 28 *dp++ = *sp++; | 
| 217 
1a7d659a952f
amr-ietf2cod: silly bugfix
 Mychaela Falconia <falcon@freecalypso.org> parents: 
216diff
changeset | 29 for (; n < MAX_SERIAL_SIZE; n++) | 
| 216 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 30 *dp++ = 0; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 31 } | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
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: 
212diff
changeset | 36 char *infname, *outfname; | 
| 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 37 FILE *inf, *outf; | 
| 216 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 38 uint8_t frm_in[MAX_IF1_BYTES]; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 39 unsigned frame_no, mode, qbit, sti, sid_mode; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 40 uint8_t ser_bits[MAX_SERIAL_SIZE]; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 41 uint16_t cod_words[COD_FORMAT_NWORDS]; | 
| 211 
78d1a6513393
amrconv: new program amr-cod-parse
 Mychaela Falconia <falcon@freecalypso.org> parents: 
148diff
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: 
215diff
changeset | 44 if (argc != 3) { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
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: 
215diff
changeset | 48 infname = argv[1]; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 49 outfname = argv[2]; | 
| 148 
bbe5669f0f29
gsmefr-cod-parse: add BE support
 Mychaela Falconia <falcon@freecalypso.org> parents: 
147diff
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: 
147diff
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: 
215diff
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: 
215diff
changeset | 56 bcmp(frm_in, amr_file_hdr, IETF_HDR_LEN)) { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
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: 
215diff
changeset | 58 infname); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 59 exit(1); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 60 } | 
| 215 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 61 outf = fopen(outfname, "w"); | 
| 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 62 if (!outf) { | 
| 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 63 perror(outfname); | 
| 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 64 exit(1); | 
| 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 65 } | 
| 216 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 66 /* padding words which will never be filled */ | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
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: 
215diff
changeset | 69 rc = getc(inf); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 70 if (rc < 0) | 
| 211 
78d1a6513393
amrconv: new program amr-cod-parse
 Mychaela Falconia <falcon@freecalypso.org> parents: 
148diff
changeset | 71 break; | 
| 216 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 72 mode = (rc & 0x78) >> 3; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 73 qbit = (rc & 4) >> 2; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 74 if (mode == MODE_NO_DATA) { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 75 cod_words[0] = TX_NO_DATA; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 76 bzero(cod_words+1, sizeof(uint16_t) * MAX_SERIAL_SIZE); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 77 cod_words[245] = 0xFFFF; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 78 goto output; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 79 } | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 80 if (mode > MRDTX) { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 81 fprintf(stderr, "error in frame #%u: invalid FT=%u\n", | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 82 frame_no, mode); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 83 exit(1); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 84 } | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
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: 
215diff
changeset | 86 if (rc != extra_bytes_per_ft[mode]) { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 87 fprintf(stderr, | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 88 "error: short read from %s on frame #%u\n", | 
| 215 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
changeset | 89 infname, frame_no); | 
| 
4c4649a5fec3
amrconv: new program amr-cod2ietf
 Mychaela Falconia <falcon@freecalypso.org> parents: 
212diff
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: 
215diff
changeset | 92 amr_if1_unpack(frm_in, ser_bits, mode); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 93 if (mode == MRDTX) { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 94 sti = (frm_in[4] & 0x10) >> 4; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 95 sid_mode = 0; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 96 if (frm_in[4] & 0x08) | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 97 sid_mode |= 1; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 98 if (frm_in[4] & 0x04) | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 99 sid_mode |= 2; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 100 if (frm_in[4] & 0x02) | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 101 sid_mode |= 4; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 102 } | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 103 bits2words(ser_bits, cod_words + 1, amr_bit_lengths[mode]); | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 104 if (mode == MRDTX) { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 105 if (qbit) | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 106 cod_words[0] = sti ? TX_SID_UPDATE | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 107 : TX_SID_FIRST; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 108 else | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 109 cod_words[0] = TX_SID_BAD; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 110 cod_words[245] = sid_mode; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 111 } else { | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 112 cod_words[0] = qbit ? TX_SPEECH_GOOD : TX_SPEECH_BAD; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 113 cod_words[245] = mode; | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
changeset | 114 } | 
| 
9d59df9b0e4e
amrconv: new program amr-ietf2cod
 Mychaela Falconia <falcon@freecalypso.org> parents: 
215diff
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: 
212diff
changeset | 117 fclose(outf); | 
| 211 
78d1a6513393
amrconv: new program amr-cod-parse
 Mychaela Falconia <falcon@freecalypso.org> parents: 
148diff
changeset | 118 exit(0); | 
| 115 
5a63294fa321
gsmefr-cod-parse test program written
 Mychaela Falconia <falcon@freecalypso.org> parents: diff
changeset | 119 } | 
