FreeCalypso > hg > gsm-codec-lib
comparison frtest/hand-test.c @ 29:d21c68b8f16c
gsmfr-hand-test: yet another debug aid
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Mon, 21 Nov 2022 03:09:39 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 28:a8fd4ff6b013 | 29:d21c68b8f16c |
|---|---|
| 1 /* | |
| 2 * This program is a debug aid that allows a developer to hand-craft input | |
| 3 * to the GSM 06.10 decoder (libgsm) and see what output magnitude it results | |
| 4 * in, in the style of gsmfr-max-out. This program reads input from an | |
| 5 * ASCII text file in the same format as gsmrec-dump, performs gsm_implode() | |
| 6 * and gsm_decode() operations and reports maximum output magnitude for | |
| 7 * each processed frame. | |
| 8 */ | |
| 9 | |
| 10 #include <ctype.h> | |
| 11 #include <stdio.h> | |
| 12 #include <stdint.h> | |
| 13 #include <stdlib.h> | |
| 14 #include <string.h> | |
| 15 #include <strings.h> | |
| 16 #include <gsm.h> | |
| 17 | |
| 18 static char *infname; | |
| 19 static FILE *inf; | |
| 20 static char linebuf[256]; | |
| 21 static int lineno; | |
| 22 | |
| 23 static | |
| 24 get_line() | |
| 25 { | |
| 26 if (!fgets(linebuf, sizeof linebuf, inf)) | |
| 27 return 0; | |
| 28 lineno++; | |
| 29 if (!index(linebuf, '\n')) { | |
| 30 fprintf(stderr, "%s line %d: too long or missing newline\n", | |
| 31 infname, lineno); | |
| 32 exit(1); | |
| 33 } | |
| 34 return 1; | |
| 35 } | |
| 36 | |
| 37 static | |
| 38 read_lar_params(params) | |
| 39 gsm_signal *params; | |
| 40 { | |
| 41 char *cp; | |
| 42 unsigned n; | |
| 43 | |
| 44 for (;;) { | |
| 45 if (!get_line()) | |
| 46 return 0; | |
| 47 for (cp = linebuf; isspace(*cp); cp++) | |
| 48 ; | |
| 49 if (*cp) | |
| 50 break; | |
| 51 } | |
| 52 if (*cp == '#') { | |
| 53 cp++; | |
| 54 if (!isdigit(*cp)) { | |
| 55 inv_syntax: fprintf(stderr, | |
| 56 "%s line %d: invalid syntax (expected LAR)\n", | |
| 57 infname, lineno); | |
| 58 exit(1); | |
| 59 } | |
| 60 while (isdigit(*cp)) | |
| 61 cp++; | |
| 62 if (*cp++ != ':') | |
| 63 goto inv_syntax; | |
| 64 while (isspace(*cp)) | |
| 65 cp++; | |
| 66 } | |
| 67 if (cp[0] != 'F' || cp[1] != 'R' || !isspace(cp[2])) | |
| 68 goto inv_syntax; | |
| 69 cp += 3; | |
| 70 for (n = 0; n < 8; n++) { | |
| 71 while (isspace(*cp)) | |
| 72 cp++; | |
| 73 if (!isdigit(*cp)) | |
| 74 goto inv_syntax; | |
| 75 params[n] = strtoul(cp, &cp, 10); | |
| 76 if (!isspace(*cp)) | |
| 77 goto inv_syntax; | |
| 78 } | |
| 79 fputs(linebuf, stdout); | |
| 80 return 1; | |
| 81 } | |
| 82 | |
| 83 static void | |
| 84 read_subframe_params(params) | |
| 85 gsm_signal *params; | |
| 86 { | |
| 87 char *cp; | |
| 88 unsigned n; | |
| 89 | |
| 90 for (;;) { | |
| 91 if (!get_line()) { | |
| 92 fprintf(stderr, | |
| 93 "%s bad: EOF in the middle of a frame\n", | |
| 94 infname); | |
| 95 exit(1); | |
| 96 } | |
| 97 for (cp = linebuf; isspace(*cp); cp++) | |
| 98 ; | |
| 99 if (*cp) | |
| 100 break; | |
| 101 } | |
| 102 for (n = 0; n < 17; n++) { | |
| 103 while (isspace(*cp)) | |
| 104 cp++; | |
| 105 if (!isdigit(*cp)) { | |
| 106 inv_syntax: fprintf(stderr, | |
| 107 "%s line %d: invalid syntax (expected subframe)\n", | |
| 108 infname, lineno); | |
| 109 exit(1); | |
| 110 } | |
| 111 params[n] = strtoul(cp, &cp, 10); | |
| 112 if (!isspace(*cp)) | |
| 113 goto inv_syntax; | |
| 114 } | |
| 115 fputs(linebuf, stdout); | |
| 116 } | |
| 117 | |
| 118 static | |
| 119 read_frame(params) | |
| 120 gsm_signal *params; | |
| 121 { | |
| 122 int rc; | |
| 123 unsigned n, idx; | |
| 124 | |
| 125 rc = read_lar_params(params); | |
| 126 if (!rc) | |
| 127 return 0; | |
| 128 idx = 8; | |
| 129 for (n = 0; n < 4; n++) { | |
| 130 read_subframe_params(params + idx); | |
| 131 idx += 17; | |
| 132 } | |
| 133 return 1; | |
| 134 } | |
| 135 | |
| 136 main(argc, argv) | |
| 137 char **argv; | |
| 138 { | |
| 139 gsm dec_state; | |
| 140 gsm_signal params[76]; | |
| 141 uint8_t frame[33]; | |
| 142 int16_t pcm[160]; | |
| 143 int rc, i; | |
| 144 unsigned samp_abs, samp_max; | |
| 145 | |
| 146 if (argc != 2) { | |
| 147 fprintf(stderr, "usage: %s input-file\n", argv[0]); | |
| 148 exit(1); | |
| 149 } | |
| 150 infname = argv[1]; | |
| 151 inf = fopen(infname, "r"); | |
| 152 if (!inf) { | |
| 153 perror(infname); | |
| 154 exit(1); | |
| 155 } | |
| 156 dec_state = gsm_create(); | |
| 157 if (!dec_state) { | |
| 158 fprintf(stderr, "gsm_create() failed!\n"); | |
| 159 exit(1); | |
| 160 } | |
| 161 for (;;) { | |
| 162 rc = read_frame(params); | |
| 163 if (!rc) | |
| 164 break; | |
| 165 gsm_implode(dec_state, params, frame); | |
| 166 gsm_decode(dec_state, frame, pcm); | |
| 167 samp_max = 0; | |
| 168 for (i = 0; i < 160; i++) { | |
| 169 if (pcm[i] >= 0) | |
| 170 samp_abs = pcm[i]; | |
| 171 else | |
| 172 samp_abs = -pcm[i]; | |
| 173 if (samp_abs > samp_max) | |
| 174 samp_max = samp_abs; | |
| 175 } | |
| 176 printf(" MAX=%u\n", samp_max); | |
| 177 } | |
| 178 exit(0); | |
| 179 } |
