comparison miscutil/fc-tch2fr.c @ 6:d57f68d0568d

fc-tch2fr utility written, added under miscutil
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 14 Jun 2016 02:45:09 +0000
parents
children
comparison
equal deleted inserted replaced
5:7eaa3307e5df 6:d57f68d0568d
1 /*
2 * Our experimental Calypso firmware enables us to capture the output of
3 * the GSM 05.03 channel decoder in the DSP, i.e., the bits leaving the
4 * channel decoder and going into the speech decoder. Our fc-shell utility
5 * allows saving this capture to a file; the captured booty includes not only
6 * the expected 260 bits per frame, but also some DSP status words which are
7 * not fully understood, but which are believed to contain indications as to
8 * whether the decoded speech frame is good or bad.
9 *
10 * My first naive thought was to save the captured speech frames in libgsm
11 * format so I could then play them with the 'play' command (SoX package)
12 * under Linux, but the problem with this naive approach is that the bad frames
13 * indication is lost, and some of the saved "speech" frames will contain
14 * utter garbage, resulting in very unkind-on-ears noises if that file is
15 * then played. I don't know what the proper solution should be; I don't know
16 * what the commercial cellphone implementations of the GSM 06.10 speech decoder
17 * (buried in black box DSPs) do when they get bad frames from the channel
18 * decoder.
19 *
20 * The present utility reproduces the naive behaviour of my previous
21 * implementation of fc-shell's tch record command: it takes hex files written
22 * by the current implementation of tch record in fc-shell, DISREGARDS the
23 * DSP status words, and blindly converts each 260-bit frame (good or bad)
24 * into libgsm format.
25 */
26
27 #include <sys/types.h>
28 #include <ctype.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 static
33 decode_hex_digit(ch)
34 {
35 if (isdigit(ch))
36 return(ch - '0');
37 else if (isupper(ch))
38 return(ch - 'A' + 10);
39 else
40 return(ch - 'a' + 10);
41 }
42
43 main(argc, argv)
44 char **argv;
45 {
46 FILE *inf, *outf;
47 char linebuf[128];
48 int lineno;
49 char *cp;
50 int i, j;
51 u_char tidsp_bytes[33], libgsm_bytes[33];
52
53 if (argc != 3) {
54 fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
55 exit(1);
56 }
57 inf = fopen(argv[1], "r");
58 if (!inf) {
59 perror(argv[1]);
60 exit(1);
61 }
62 outf = fopen(argv[2], "w");
63 if (!outf) {
64 perror(argv[2]);
65 exit(1);
66 }
67 for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
68 /* skip DSP status words */
69 cp = linebuf;
70 for (i = 0; i < 3; i++) {
71 for (j = 0; j < 4; j++) {
72 if (!isxdigit(*cp++)) {
73 invalid: fprintf(stderr,
74 "error: %s is not in the expected format\n",
75 argv[1]);
76 exit(1);
77 }
78 }
79 if (*cp++ != ' ')
80 goto invalid;
81 }
82 /* read the frame bits */
83 for (i = 0; i < 33; i++) {
84 if (!isxdigit(cp[0]) || !isxdigit(cp[1]))
85 goto invalid;
86 tidsp_bytes[i] = (decode_hex_digit(cp[0]) << 4) |
87 decode_hex_digit(cp[1]);
88 cp += 2;
89 }
90 gsm0610_tidsp_to_libgsm(tidsp_bytes, libgsm_bytes);
91 fwrite(libgsm_bytes, 1, 33, outf);
92 }
93 exit(0);
94 }