FreeCalypso > hg > gsm-codec-lib
view efrtest/etsi-dec.c @ 97:e5ee684c6d29
efrtest/etsi-dec.c: off-by-1 error in frame bit packing
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 26 Nov 2022 21:06:48 +0000 |
parents | 9cf1355bc071 |
children | 8ed838709897 |
line wrap: on
line source
/* * gsmefr-etsi-dec is a test program for our EFR decoder: it reads ETSI's * .dec format as input and writes raw 16-bit PCM (same as ETSI's *.out) * as output, allowing our decoder to be tested with ETSI's official test * sequences. * * ETSI input and output files are read and written in LE byte order, * matching the official test sequences in ts_100725v050200p0.zip. */ #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "../libgsmefr/gsm_efr.h" #define ETSI_DEC_NWORDS 247 static int read_input(inf, bitvec, filename_for_errs) FILE *inf; uint8_t *bitvec; char *filename_for_errs; { uint8_t file_bytes[ETSI_DEC_NWORDS * 2], *sp; int cc; unsigned n; cc = fread(file_bytes, 2, ETSI_DEC_NWORDS, inf); if (cc == 0) return 0; if (cc != ETSI_DEC_NWORDS) { fprintf(stderr, "error: short read from %s\n", filename_for_errs); exit(1); } sp = file_bytes; for (n = 0; n < ETSI_DEC_NWORDS; n++) { if (sp[1]) { fprintf(stderr, "error in %s: non-zero in what should be LE upper byte\n", filename_for_errs); exit(1); } bitvec[n] = sp[0]; sp += 2; } return 1; } static void bits2frame(input_bits, frame, filename_for_errs, frame_no) uint8_t *input_bits, *frame; char *filename_for_errs; unsigned frame_no; { uint8_t bits[248], *sp, *dp; unsigned nb, byte, mask; bits[0] = 1; bits[1] = 1; bits[2] = 0; bits[3] = 0; bcopy(input_bits, bits + 4, 244); sp = bits; dp = frame; for (nb = 0; nb < EFR_RTP_FRAME_LEN; nb++) { byte = 0; for (mask = 0x80; mask; mask >>= 1) { if (*sp > 1) { fprintf(stderr, "error in %s frame #%u: data bit > 1\n", filename_for_errs, frame_no); exit(1); } if (*sp) byte |= mask; sp++; } *dp++ = byte; } } static void write_pcm_le(outf, pcm) FILE *outf; int16_t *pcm; { uint8_t bytes[320], *dp; int16_t samp; unsigned n; dp = bytes; for (n = 0; n < 160; n++) { samp = pcm[n]; *dp++ = samp & 0xFF; *dp++ = (samp >> 8) & 0xFF; } fwrite(bytes, 2, 160, outf); } main(argc, argv) char **argv; { FILE *inf, *outf; struct EFR_decoder_state *state; unsigned frame_no; uint8_t input_bits[ETSI_DEC_NWORDS], frame[EFR_RTP_FRAME_LEN]; int16_t pcm[160]; int rc; if (argc != 3) { fprintf(stderr, "usage: %s input.dec output.out\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); } state = EFR_decoder_create(); if (!state) { perror("EFR_decoder_create()"); exit(1); } for (frame_no = 0; ; frame_no++) { rc = read_input(inf, input_bits, argv[1]); if (!rc) break; if (input_bits[0] > 1) { fprintf(stderr, "error in %s frame #%u: BFI > 1\n", argv[1], frame_no); exit(1); } bits2frame(input_bits + 1, frame, argv[1], frame_no); if (input_bits[245] > 2) { fprintf(stderr, "error in %s frame #%u: SID > 2\n", argv[1], frame_no); exit(1); } if (input_bits[246] > 1) { fprintf(stderr, "error in %s frame #%u: TAF > 1\n", argv[1], frame_no); exit(1); } rc = EFR_sid_classify(frame); if (input_bits[245] != rc) { fprintf(stderr, "warning: frame #%u has mismatching SID (file says %u, analysis yields %d)\n", frame_no, input_bits[245], rc); } EFR_decode_frame(state, frame, input_bits[0], input_bits[246], pcm); write_pcm_le(outf, pcm); } fclose(outf); exit(0); }