comparison trau-decode/extr-main.c @ 9:0565aaa84b17

trau-decode: implement trau-extr program
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 24 May 2024 19:44:14 +0000
parents
children
comparison
equal deleted inserted replaced
8:85662304252e 9:0565aaa84b17
1 /*
2 * This program reads a 64 kbit/s timeslot recording file with a focus
3 * on a single sub-timeslot just like trau-parse, but it needs to be
4 * invoked with a starting and ending offset for the frame-aligned
5 * portion of interest (found with trau-parse), and it saves (converts)
6 * the selected stream of TRAU-UL frames to a Themyscira gsmx file.
7 */
8
9 #include <sys/types.h>
10 #include <stdio.h>
11 #include <stdint.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <strings.h>
15
16 static void
17 reduce_to_subslot(buf, right_shift)
18 uint8_t *buf;
19 {
20 unsigned n;
21
22 for (n = 0; n < 160; n++) {
23 buf[n] >>= right_shift;
24 buf[n] &= 3;
25 }
26 }
27
28 static void
29 unpack_dibits(dibits, frame_bits)
30 uint8_t *dibits, *frame_bits;
31 {
32 int i, inb;
33 uint8_t *op;
34
35 op = frame_bits;
36 for (i = 0; i < 160; i++) {
37 inb = dibits[i];
38 if (inb & 2)
39 *op++ = 1;
40 else
41 *op++ = 0;
42 if (inb & 1)
43 *op++ = 1;
44 else
45 *op++ = 0;
46 }
47 }
48
49 static unsigned
50 bits_to_num(bits, nbits)
51 uint8_t *bits;
52 unsigned nbits;
53 {
54 unsigned accum;
55 unsigned n;
56
57 accum = 0;
58 for (n = 0; n < nbits; n++) {
59 accum <<= 1;
60 if (*bits)
61 accum |= 1;
62 bits++;
63 }
64 return accum;
65 }
66
67 static void
68 collect_d_bits(frame_bits, d_bits)
69 uint8_t *frame_bits, *d_bits;
70 {
71 bcopy(frame_bits + 33, d_bits, 15);
72 bcopy(frame_bits + 49, d_bits + 15, 15);
73 bcopy(frame_bits + 65, d_bits + 30, 15);
74 bcopy(frame_bits + 81, d_bits + 45, 15);
75 bcopy(frame_bits + 97, d_bits + 60, 15);
76 bcopy(frame_bits + 113, d_bits + 75, 15);
77 bcopy(frame_bits + 129, d_bits + 90, 15);
78 bcopy(frame_bits + 145, d_bits + 105, 15);
79 bcopy(frame_bits + 161, d_bits + 120, 15);
80 bcopy(frame_bits + 177, d_bits + 135, 15);
81 bcopy(frame_bits + 193, d_bits + 150, 15);
82 bcopy(frame_bits + 209, d_bits + 165, 15);
83 bcopy(frame_bits + 225, d_bits + 180, 15);
84 bcopy(frame_bits + 241, d_bits + 195, 15);
85 bcopy(frame_bits + 257, d_bits + 210, 15);
86 bcopy(frame_bits + 273, d_bits + 225, 15);
87 bcopy(frame_bits + 289, d_bits + 240, 15);
88 bcopy(frame_bits + 305, d_bits + 255, 5);
89 }
90
91 static void
92 process_frame(cur_offset, dibits, outf)
93 u_long cur_offset;
94 uint8_t *dibits;
95 FILE *outf;
96 {
97 uint8_t frame_bits[320], d_bits[260];
98 unsigned c1_5;
99
100 unpack_dibits(dibits, frame_bits);
101 if (frame_bits[28]) { /* C12 aka BFI */
102 putc(0xBF, outf);
103 putc(frame_bits[31], outf); /* C15 aka TAF */
104 return;
105 }
106 collect_d_bits(frame_bits, d_bits);
107 c1_5 = bits_to_num(frame_bits + 17, 5);
108 switch (c1_5) {
109 case 0x02:
110 convert_fr_frame(d_bits, outf);
111 break;
112 case 0x1A:
113 convert_efr_frame(d_bits, outf);
114 break;
115 default:
116 fprintf(stderr,
117 "error: unknown frame type 0x%x at file offset 0x%lx\n",
118 c1_5, cur_offset);
119 exit(1);
120 }
121 }
122
123 main(argc, argv)
124 char **argv;
125 {
126 FILE *inf, *outf;
127 int subslot, right_shift;
128 u_long start_offset, end_offset, cur_offset;
129 uint8_t readbuf[160];
130 int cc;
131
132 if (argc != 6) {
133 fprintf(stderr, "usage: %s binfile subslot start end outfile\n",
134 argv[0]);
135 exit(1);
136 }
137 inf = fopen(argv[1], "r");
138 if (!inf) {
139 perror(argv[1]);
140 exit(1);
141 }
142 subslot = atoi(argv[2]);
143 if (subslot < 0 || subslot > 3) {
144 fprintf(stderr, "error: invalid subslot argument\n");
145 exit(1);
146 }
147 right_shift = (3 - subslot) * 2;
148 start_offset = strtoul(argv[3], 0, 0);
149 fseek(inf, start_offset, SEEK_SET);
150 end_offset = strtoul(argv[4], 0, 0);
151 outf = fopen(argv[5], "w");
152 if (!outf) {
153 perror(argv[5]);
154 exit(1);
155 }
156 for (cur_offset = start_offset; ; cur_offset += 160) {
157 if (end_offset && cur_offset >= end_offset)
158 break;
159 cc = fread(readbuf, 1, 160, inf);
160 if (cc < 160)
161 break;
162 reduce_to_subslot(readbuf, right_shift);
163 process_frame(cur_offset, readbuf, outf);
164 }
165 exit(0);
166 }