FreeCalypso > hg > freecalypso-tools
view tchtools/fc-tch2fr.c @ 909:1e9fe07f8f09
doc/Voice-memo-utils: new article
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 29 Dec 2022 21:03:11 +0000 |
parents | a7ad6b39e01b |
children |
line wrap: on
line source
/* * This program reads TCH downlink capture files in the old format from 2016 * (the format which fc-shell tch record will write if the firmware running * on the Calypso GSM device is an old version that emits TCH DL bits in * the old format from 2016), completely *disregards* all 3 status words * including the essential word of control flags, converts the 260-bit * payload portion of each frame into standard libgsm/RTP format, and * writes the result into a .gsm binary file. * * This program was written in 2016, at that time we (FreeCalypso team) * did not have a proper understanding of how the complete TCH DL processing * chain works - we particularly missed the Rx DTX handler block that MUST * be present between the output of the GSM 05.03 channel decoder and the * input to the GSM 06.10 speech decoder - and therefore the function * performed by this program is a bogo-transform. * * This bogo-transform program is kept as part of FC host tools package * only for backward compatibility - for actual decoding of TCH DL captures, * please use our new gsmfr-dlcap-* and gsmefr-dlcap-* utilities that are * maintained as part of Themyscira Wireless GSM codec libraries & utilities * package. */ #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); }