FreeCalypso > hg > gsm-codec-lib
comparison amrconv/oa2bwe.c @ 590:6b2900fe20f4
amrconv: new program amr-hex-oa2bwe
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Thu, 06 Nov 2025 22:42:09 +0000 |
| parents | amrconv/hex2ietf.c@4d6ccca0c687 |
| children |
comparison
equal
deleted
inserted
replaced
| 589:e414d138c607 | 590:6b2900fe20f4 |
|---|---|
| 1 /* | |
| 2 * This program reads a TW-TS-005 hexadecimal file, expects each record to be | |
| 3 * AMR in OA/OAX format, converts it to BWE format, and writes the output into | |
| 4 * a new TW-TS-005 hex file. | |
| 5 */ | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 #include <stdint.h> | |
| 9 #include <stdlib.h> | |
| 10 #include <string.h> | |
| 11 #include <strings.h> | |
| 12 #include "../libtest/tw5reader.h" | |
| 13 #include "../libtest/tw5writer.h" | |
| 14 #include "amr_defs.h" | |
| 15 | |
| 16 extern const uint8_t pl_total_bytes_oa[9], pl_total_bytes_bwe[9]; | |
| 17 | |
| 18 main(argc, argv) | |
| 19 char **argv; | |
| 20 { | |
| 21 FILE *inf, *outf; | |
| 22 unsigned lineno; | |
| 23 uint8_t frm_in[TWTS005_MAX_FRAME], frm_out[MAX_IF1_BYTES + 2]; | |
| 24 unsigned frm_in_len, cmr, ft, expect_len, out_len, n; | |
| 25 int rc; | |
| 26 | |
| 27 if (argc != 3) { | |
| 28 fprintf(stderr, "usage: %s amr-oa.hex amr-bwe.hex\n", argv[0]); | |
| 29 exit(1); | |
| 30 } | |
| 31 inf = fopen(argv[1], "r"); | |
| 32 if (!inf) { | |
| 33 perror(argv[1]); | |
| 34 exit(1); | |
| 35 } | |
| 36 lineno = 0; | |
| 37 outf = fopen(argv[2], "w"); | |
| 38 if (!outf) { | |
| 39 perror(argv[2]); | |
| 40 exit(1); | |
| 41 } | |
| 42 for (;;) { | |
| 43 rc = twts005_read_frame(inf, &lineno, frm_in, &frm_in_len); | |
| 44 if (rc < 0) { | |
| 45 fprintf(stderr, "%s line %u: not valid TW-TS-005\n", | |
| 46 argv[1], lineno); | |
| 47 exit(1); | |
| 48 } | |
| 49 if (!rc) | |
| 50 break; | |
| 51 if (frm_in_len == 0) { | |
| 52 fputs("NULL\n", outf); | |
| 53 continue; | |
| 54 } | |
| 55 if (frm_in_len < 2) { | |
| 56 inv_payload: fprintf(stderr, | |
| 57 "%s line %u: payload is not valid AMR OA\n", | |
| 58 argv[1], lineno); | |
| 59 exit(1); | |
| 60 } | |
| 61 cmr = frm_in[0] >> 4; | |
| 62 if (cmr > MR122 && cmr != MODE_NO_DATA) | |
| 63 goto inv_payload; | |
| 64 if (frm_in[1] & 0x80) | |
| 65 goto inv_payload; | |
| 66 ft = (frm_in[1] & 0x78) >> 3; | |
| 67 if (ft <= MRDTX) | |
| 68 expect_len = pl_total_bytes_oa[ft]; | |
| 69 else if (ft == MODE_NO_DATA) | |
| 70 expect_len = 2; | |
| 71 else | |
| 72 goto inv_payload; | |
| 73 if (frm_in_len < expect_len) | |
| 74 goto inv_payload; | |
| 75 /* With some frame types, the number of padding bits in BWE | |
| 76 * output will be greater than the number of padding bits in | |
| 77 * OA input. The easiest way to ensure zero fill in those bits | |
| 78 * is to zero the byte just past the input. Because our frm_in | |
| 79 * buffer is sized for TW-TS-005, we have room. | |
| 80 */ | |
| 81 frm_in[expect_len] = 0; | |
| 82 /* proceed to output */ | |
| 83 if (ft != MODE_NO_DATA) | |
| 84 out_len = pl_total_bytes_bwe[ft]; | |
| 85 else | |
| 86 out_len = 2; | |
| 87 frm_out[0] = (cmr << 4) | (ft >> 1); | |
| 88 frm_out[1] = ((frm_in[1] & 0x0C) << 4) | (frm_in[2] >> 2); | |
| 89 for (n = 2; n < out_len; n++) | |
| 90 frm_out[n] = (frm_in[n] << 6) | (frm_in[n+1] >> 2); | |
| 91 emit_hex_frame(outf, frm_out, out_len); | |
| 92 } | |
| 93 exit(0); | |
| 94 } |
