# HG changeset patch # User Mychaela Falconia # Date 1724308752 0 # Node ID e95e145f4b32adca079cc0703a178e764be3f5bc # Parent f27bc1e173115bfdb53b0f1263f40a5e10f599ec fr-sid: generate test sequence diff -r f27bc1e17311 -r e95e145f4b32 .hgignore --- a/.hgignore Thu Aug 22 05:00:08 2024 +0000 +++ b/.hgignore Thu Aug 22 06:39:12 2024 +0000 @@ -29,6 +29,8 @@ ^efr-sid/mk-sid-test$ ^efr-sid/mk-sid-test2$ +^fr-sid/mk-sid-test$ + ^hr-sid/misorder$ ^hr-sid/sidgen$ diff -r f27bc1e17311 -r e95e145f4b32 fr-sid/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fr-sid/Makefile Thu Aug 22 06:39:12 2024 +0000 @@ -0,0 +1,26 @@ +CC= gcc +CFLAGS= -O2 +PROG= mk-sid-test +INPUT= goodsp-frame41.gsmx + +OUT_NATIVE= fr1-sid-test.gsmx +OUT_HEX= fr1-sid-test.hex +OUT_TCH= fr1-sid-test.tch +OUTPUTS= ${OUT_NATIVE} ${OUT_HEX} ${OUT_TCH} + +all: ${PROG} ${OUTPUTS} + +${PROG}: ${PROG}.c + ${CC} ${CFLAGS} -o $@ $@.c + +${OUT_NATIVE}: ${PROG} ${INPUT} + ./${PROG} ${INPUT} $@ + +${OUT_HEX}: ${OUT_NATIVE} + ../utils/gen-hex-lines ${OUT_NATIVE} $@ 33 + +${OUT_TCH}: ${OUT_NATIVE} + fc-fr2tch ${OUT_NATIVE} $@ + +clean: + rm -f ${PROG} *.o ${OUT_NATIVE} *.hex *.tch diff -r f27bc1e17311 -r e95e145f4b32 fr-sid/mk-sid-test.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fr-sid/mk-sid-test.c Thu Aug 22 06:39:12 2024 +0000 @@ -0,0 +1,156 @@ +/* + * This program generates a set of FRv1 codec frames based on a single input + * frame (in gsmx packed binary format) that is expected to be a perfect SID. + * The output frame set is intended to serve as a unit test for the + * bit-counting SID classification function; it will contain different + * extents of bit alteration to produce valid SID, invalid SID and non-SID + * speech classifications. + */ + +#include +#include +#include +#include +#include +#include + +static uint8_t input_frame[GSMFR_RTP_FRAME_LEN]; +static FILE *outf; + +static void +read_input_file(filename) + char *filename; +{ + FILE *inf; + int cc; + + inf = fopen(filename, "r"); + if (!inf) { + perror(filename); + exit(1); + } + cc = fread(input_frame, GSMFR_RTP_FRAME_LEN, 1, inf); + if (cc < 1) { + fprintf(stderr, "error: short read from %s\n", filename); + exit(1); + } + fclose(inf); + if ((input_frame[0] & 0xF0) != 0xD0) { + fprintf(stderr, + "error: bytes read from %s are not a GSM-FR frame\n", + filename); + exit(1); + } +} + +static const unsigned short sid_field_bits[95] = { + 57, 58, 60, 61, 63, 64, 66, 67, 69, 70, 72, 73, + 75, 76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91, + 93, 94, 113, 114, 116, 117, 119, 120, 122, 123, + 125, 126, 128, 129, 131, 132, 134, 135, 137, + 138, 140, 141, 143, 144, 146, 147, 149, 150, + 169, 170, 172, 173, 175, 176, 178, 179, 181, + 182, 184, 185, 187, 188, 190, 191, 193, 194, + 196, 197, 199, 200, 202, 203, 205, 206, 225, + 226, 228, 229, 231, 232, 234, 235, 237, 240, + 243, 246, 249, 252, 255, 258, 261 +}; + +static void +set_bit(frame, bitnum) + uint8_t *frame; + unsigned bitnum; +{ + unsigned bytenum = bitnum >> 3; + unsigned bit_in_byte = 7 - (bitnum & 7); + unsigned bitmask = 1 << bit_in_byte; + + frame[bytenum] |= bitmask; +} + +static void +emit_out_frame(frame) + uint8_t *frame; +{ + fwrite(frame, GSMFR_RTP_FRAME_LEN, 1, outf); +} + +static void +emit_1bit_errors() +{ + uint8_t frame[GSMFR_RTP_FRAME_LEN]; + unsigned n; + + for (n = 0; n < 95; n++) { + bcopy(input_frame, frame, GSMFR_RTP_FRAME_LEN); + set_bit(frame, sid_field_bits[n]); + emit_out_frame(frame); + } +} + +static void +emit_2bit_errors() +{ + uint8_t frame[GSMFR_RTP_FRAME_LEN]; + unsigned n; + + for (n = 0; n < 48; n++) { + bcopy(input_frame, frame, GSMFR_RTP_FRAME_LEN); + set_bit(frame, sid_field_bits[n]); + set_bit(frame, sid_field_bits[n + 47]); + emit_out_frame(frame); + } +} + +static void +emit_15bit_errors() +{ + uint8_t frame[GSMFR_RTP_FRAME_LEN]; + unsigned i, j; + + for (i = 0; i < 11; i++) { + bcopy(input_frame, frame, GSMFR_RTP_FRAME_LEN); + for (j = 0; j < 15; j++) + set_bit(frame, sid_field_bits[j * 6 + i]); + emit_out_frame(frame); + } +} + +static void +emit_16bit_errors() +{ + uint8_t frame[GSMFR_RTP_FRAME_LEN]; + unsigned i, j; + + for (i = 0; i < 20; i++) { + bcopy(input_frame, frame, GSMFR_RTP_FRAME_LEN); + for (j = 0; j < 16; j++) + set_bit(frame, sid_field_bits[j * 5 + i]); + emit_out_frame(frame); + } +} + +main(argc, argv) + char **argv; +{ + if (argc != 3) { + fprintf(stderr, "usage: %s input.gsmx output.gsmx\n", argv[0]); + exit(1); + } + read_input_file(argv[1]); + outf = fopen(argv[2], "w"); + if (!outf) { + perror(argv[2]); + exit(1); + } + /* emit the perfect, error-free SID first */ + emit_out_frame(input_frame); + /* now different bit-error possibilities */ + emit_1bit_errors(); + emit_2bit_errors(); + emit_15bit_errors(); + emit_16bit_errors(); + /* all done */ + fclose(outf); + exit(0); +}