FreeCalypso > hg > freecalypso-tools
view miscutil/fc-tch2fr.c @ 787:ae237e4e8d9b
doc/Target-utils: simagent addition documented
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 13 Mar 2021 23:27:58 +0000 |
parents | d57f68d0568d |
children |
line wrap: on
line source
/* * Our experimental Calypso firmware enables us to capture the output of * the GSM 05.03 channel decoder in the DSP, i.e., the bits leaving the * channel decoder and going into the speech decoder. Our fc-shell utility * allows saving this capture to a file; the captured booty includes not only * the expected 260 bits per frame, but also some DSP status words which are * not fully understood, but which are believed to contain indications as to * whether the decoded speech frame is good or bad. * * My first naive thought was to save the captured speech frames in libgsm * format so I could then play them with the 'play' command (SoX package) * under Linux, but the problem with this naive approach is that the bad frames * indication is lost, and some of the saved "speech" frames will contain * utter garbage, resulting in very unkind-on-ears noises if that file is * then played. I don't know what the proper solution should be; I don't know * what the commercial cellphone implementations of the GSM 06.10 speech decoder * (buried in black box DSPs) do when they get bad frames from the channel * decoder. * * The present utility reproduces the naive behaviour of my previous * implementation of fc-shell's tch record command: it takes hex files written * by the current implementation of tch record in fc-shell, DISREGARDS the * DSP status words, and blindly converts each 260-bit frame (good or bad) * into libgsm format. */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> static decode_hex_digit(ch) { if (isdigit(ch)) return(ch - '0'); else if (isupper(ch)) return(ch - 'A' + 10); else return(ch - 'a' + 10); } main(argc, argv) char **argv; { FILE *inf, *outf; char linebuf[128]; int lineno; char *cp; int i, j; u_char tidsp_bytes[33], libgsm_bytes[33]; if (argc != 3) { fprintf(stderr, "usage: %s infile outfile\n", argv[0]); exit(1); } inf = fopen(argv[1], "r"); if (!inf) { perror(argv[1]); exit(1); } outf = fopen(argv[2], "w"); if (!outf) { perror(argv[2]); exit(1); } for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) { /* skip DSP status words */ cp = linebuf; for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { if (!isxdigit(*cp++)) { invalid: fprintf(stderr, "error: %s is not in the expected format\n", argv[1]); exit(1); } } if (*cp++ != ' ') goto invalid; } /* read the frame bits */ for (i = 0; i < 33; i++) { if (!isxdigit(cp[0]) || !isxdigit(cp[1])) goto invalid; tidsp_bytes[i] = (decode_hex_digit(cp[0]) << 4) | decode_hex_digit(cp[1]); cp += 2; } gsm0610_tidsp_to_libgsm(tidsp_bytes, libgsm_bytes); fwrite(libgsm_bytes, 1, 33, outf); } exit(0); }