5
|
1 /*
|
|
2 * SpanDSP - a series of DSP components for telephony
|
|
3 *
|
|
4 * gsm0610_tests.c - Test the GSM 06.10 FR codec.
|
|
5 *
|
|
6 * Written by Steve Underwood <steveu@coppice.org>
|
|
7 *
|
|
8 * Copyright (C) 2006 Steve Underwood
|
|
9 *
|
|
10 * All rights reserved.
|
|
11 *
|
|
12 * This program is free software; you can redistribute it and/or modify
|
|
13 * it under the terms of the GNU General Public License version 2, as
|
|
14 * published by the Free Software Foundation.
|
|
15 *
|
|
16 * This program is distributed in the hope that it will be useful,
|
|
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19 * GNU General Public License for more details.
|
|
20 *
|
|
21 * You should have received a copy of the GNU General Public License
|
|
22 * along with this program; if not, write to the Free Software
|
|
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
24 *
|
|
25 * $Id: gsm0610_tests.c,v 1.6 2006/11/19 14:07:27 steveu Exp $
|
|
26 */
|
|
27
|
|
28 /*! \file */
|
|
29
|
|
30 /*! \page gsm0610_tests_page GSM 06.10 full rate codec tests
|
|
31 \section gsm0610_tests_page_sec_1 What does it do?
|
|
32 Two sets of tests are performed:
|
|
33 - The tests defined in the GSM 06.10 specification, using the test data files supplied with
|
|
34 the specification.
|
|
35 - A generally audio quality test, consisting of compressing and decompressing a speeech
|
|
36 file for audible comparison.
|
|
37
|
|
38 The speech file should be recorded at 16 bits/sample, 8000 samples/second, and named
|
|
39 "pre_gsm0610.wav".
|
|
40
|
|
41 \section gsm0610_tests_page_sec_2 How is it used?
|
|
42 To perform the tests in the GSM 06.10 specification you need to obtain the test data files from the
|
|
43 specification. These are copyright material, and so cannot be distributed with spandsp. They can,
|
|
44 however, be freely downloaded from the ETSI web site.
|
|
45
|
|
46 The files, containing test vectors, which are supplied with the GSM 06.10 specification, should be
|
|
47 copied to etsitests/gsm0610/unpacked so the files are arranged in the following directories.
|
|
48
|
|
49 ./fr_A:
|
|
50 Seq01-A.cod Seq01-A.inp Seq01-A.out
|
|
51 Seq02-A.cod Seq02-A.inp Seq02-A.out
|
|
52 Seq03-A.cod Seq03-A.inp Seq03-A.out
|
|
53 Seq04-A.cod Seq04-A.inp Seq04-A.out
|
|
54 Seq05-A.out
|
|
55
|
|
56 ./fr_L:
|
|
57 Seq01.cod Seq01.inp Seq01.out
|
|
58 Seq02.cod Seq02.inp Seq02.out
|
|
59 Seq03.cod Seq03.inp Seq03.out
|
|
60 Seq04.cod Seq04.inp Seq04.out
|
|
61 Seq05.cod Seq05.out
|
|
62
|
|
63 ./fr_U:
|
|
64 Seq01-U.cod Seq01-U.inp Seq01-U.out
|
|
65 Seq02-U.cod Seq02-U.inp Seq02-U.out
|
|
66 Seq03-U.cod Seq03-U.inp Seq03-U.out
|
|
67 Seq04-U.cod Seq04-U.inp Seq04-U.out
|
|
68 Seq05-U.out
|
|
69
|
|
70 ./fr_homing_A:
|
|
71 Homing01_A.out
|
|
72 Seq01H_A.cod Seq01H_A.inp Seq01H_A.out
|
|
73 Seq02H_A.cod Seq02H_A.inp Seq02H_A.out
|
|
74 Seq03H_A.cod Seq03H_A.inp Seq03H_A.out
|
|
75 Seq04H_A.cod Seq04H_A.inp Seq04H_A.out
|
|
76 Seq05H_A.out
|
|
77 Seq06H_A.cod Seq06H_A.inp
|
|
78
|
|
79 ./fr_homing_L:
|
|
80 Homing01.cod Homing01.out
|
|
81 Seq01h.cod Seq01h.inp Seq01h.out
|
|
82 Seq02h.cod Seq02h.inp Seq02h.out
|
|
83 Seq03h.cod Seq03h.inp Seq03h.out
|
|
84 Seq04h.cod Seq04h.inp Seq04h.out
|
|
85 Seq05h.cod Seq05h.out
|
|
86 Seq06h.cod Seq06h.inp
|
|
87
|
|
88 ./fr_homing_U:
|
|
89 Homing01_U.out
|
|
90 Seq01H_U.cod Seq01H_U.inp Seq01H_U.out
|
|
91 Seq02H_U.cod Seq02H_U.inp Seq02H_U.out
|
|
92 Seq03H_U.cod Seq03H_U.inp Seq03H_U.out
|
|
93 Seq04H_U.cod Seq04H_U.inp Seq04H_U.out
|
|
94 Seq05H_U.out
|
|
95 Seq06H_U.cod Seq06H_U.inp
|
|
96
|
|
97 ./fr_sync_A:
|
|
98 Seqsync_A.inp
|
|
99 Sync000_A.cod --to-- Sync159_A.cod
|
|
100
|
|
101 ./fr_sync_L:
|
|
102 Bitsync.inp
|
|
103 Seqsync.inp
|
|
104 Sync000.cod --to-- Sync159.cod
|
|
105
|
|
106 ./fr_sync_U:
|
|
107 Seqsync_U.inp
|
|
108 Sync000_U.cod --to-- Sync159_U.cod
|
|
109
|
|
110 This is different from the directory structure in which they are supplied. Also, the files names are a little
|
|
111 different. The supplied names are messy, and inconsistent across the sets. The names required by these tests
|
|
112 just clean up these inconsistencies. Note that you will need a Windows machine to unpack some of the supplied
|
|
113 files.
|
|
114
|
|
115 To perform a general audio quality test, gsm0610_tests should be run. The file ../localtests/short_nb_voice.wav
|
|
116 will be compressed to GSM 06.10 data, decompressed, and the resulting audio stored in post_gsm0610.wav.
|
|
117 */
|
|
118
|
|
119 #ifdef HAVE_CONFIG_H
|
|
120 #include "config.h"
|
|
121 #endif
|
|
122
|
|
123 #include <inttypes.h>
|
|
124 #include <stdlib.h>
|
|
125 #include <unistd.h>
|
|
126 #include <stdio.h>
|
|
127 #include <string.h>
|
|
128 #if defined(HAVE_TGMATH_H)
|
|
129 #include <tgmath.h>
|
|
130 #endif
|
|
131 #if defined(HAVE_MATH_H)
|
|
132 #include <math.h>
|
|
133 #endif
|
|
134 #include <assert.h>
|
|
135 #include <fcntl.h>
|
|
136 #include <ctype.h>
|
|
137 #include <stdio.h>
|
|
138 #include <audiofile.h>
|
|
139 #include <tiffio.h>
|
|
140
|
|
141 #include "spandsp.h"
|
|
142
|
|
143 #define BLOCK_LEN 160
|
|
144
|
|
145 #define TEST_DIR "../etsitests/gsm0610/unpacked/fr_"
|
|
146
|
|
147 #define IN_FILE_NAME "../localtests/short_nb_voice.wav"
|
|
148 #define OUT_FILE_NAME "post_gsm0610.wav"
|
|
149
|
|
150 #define HIST_LEN 1000
|
|
151
|
|
152 uint8_t law_in_vector[1000000];
|
|
153 int16_t in_vector[1000000];
|
|
154 uint16_t code_vector_buf[1000000];
|
|
155 uint8_t code_vector[1000000];
|
|
156 uint8_t ref_code_vector[1000000];
|
|
157 uint8_t decoder_code_vector[1000000];
|
|
158 uint8_t law_out_vector[1000000];
|
|
159 int16_t out_vector[1000000];
|
|
160 int16_t ref_out_vector[1000000];
|
|
161 uint8_t ref_law_out_vector[1000000];
|
|
162 int vector_len;
|
|
163
|
|
164 static int get_test_vector(int full, int disk, const char *name)
|
|
165 {
|
|
166 char buf[500];
|
|
167 int in;
|
|
168 int len;
|
|
169 int i;
|
|
170
|
|
171 if (full)
|
|
172 {
|
|
173 sprintf(buf, "%s%c/%s.inp", TEST_DIR, 'L', name);
|
|
174 if ((in = open(buf, O_RDONLY)) < 0)
|
|
175 {
|
|
176 fprintf(stderr, "Cannot open %s\n", buf);
|
|
177 exit(2);
|
|
178 }
|
|
179 len = read(in, in_vector, 1000000);
|
|
180 close(in);
|
|
181 len /= sizeof(int16_t);
|
|
182 vector_len = len;
|
|
183 }
|
|
184
|
|
185 sprintf(buf, "%s%c/%s.out", TEST_DIR, 'L', name);
|
|
186 if ((in = open(buf, O_RDONLY)) < 0)
|
|
187 {
|
|
188 fprintf(stderr, "Cannot open %s\n", buf);
|
|
189 exit(2);
|
|
190 }
|
|
191 len = read(in, ref_out_vector, 1000000);
|
|
192 close(in);
|
|
193 len /= sizeof(int16_t);
|
|
194 if (full)
|
|
195 {
|
|
196 if (len != vector_len)
|
|
197 {
|
|
198 fprintf(stderr, "Input and reference vector lengths do not match - %d %d\n", vector_len, len);
|
|
199 exit(2);
|
|
200 }
|
|
201 }
|
|
202 else
|
|
203 {
|
|
204 vector_len = len;
|
|
205 }
|
|
206
|
|
207 sprintf(buf, "%s%c/%s.cod", TEST_DIR, 'L', name);
|
|
208 if ((in = open(buf, O_RDONLY)) < 0)
|
|
209 {
|
|
210 fprintf(stderr, "Cannot open %s\n", buf);
|
|
211 exit(2);
|
|
212 }
|
|
213 len = read(in, code_vector_buf, 1000000);
|
|
214 close(in);
|
|
215 len /= sizeof(int16_t);
|
|
216 for (i = 0; i < len; i++)
|
|
217 {
|
|
218 ref_code_vector[i] = code_vector_buf[i];
|
|
219 decoder_code_vector[i] = code_vector_buf[i];
|
|
220 }
|
|
221 if (len*BLOCK_LEN != vector_len*76)
|
|
222 {
|
|
223 fprintf(stderr, "Input and code vector lengths do not match - %d %d\n", vector_len, len);
|
|
224 exit(2);
|
|
225 }
|
|
226
|
|
227 return len;
|
|
228 }
|
|
229
|
|
230 static int get_law_test_vector(int full, int law, const char *name)
|
|
231 {
|
|
232 char buf[500];
|
|
233 int in;
|
|
234 int len;
|
|
235 int i;
|
|
236 int law_uc;
|
|
237
|
|
238 law_uc = toupper(law);
|
|
239
|
|
240 if (full)
|
|
241 {
|
|
242 sprintf(buf, "%s%c/%s-%c.inp", TEST_DIR, law_uc, name, law_uc);
|
|
243 if ((in = open(buf, O_RDONLY)) < 0)
|
|
244 {
|
|
245 fprintf(stderr, "Cannot open %s\n", buf);
|
|
246 exit(2);
|
|
247 }
|
|
248 len = read(in, law_in_vector, 1000000);
|
|
249 close(in);
|
|
250 vector_len = len;
|
|
251
|
|
252 sprintf(buf, "%s%c/%s-%c.cod", TEST_DIR, law_uc, name, law_uc);
|
|
253 if ((in = open(buf, O_RDONLY)) < 0)
|
|
254 {
|
|
255 fprintf(stderr, "Cannot open %s\n", buf);
|
|
256 exit(2);
|
|
257 }
|
|
258 len = read(in, code_vector_buf, 1000000);
|
|
259 close(in);
|
|
260 len /= sizeof(int16_t);
|
|
261 for (i = 0; i < len; i++)
|
|
262 ref_code_vector[i] = code_vector_buf[i];
|
|
263 if (len*BLOCK_LEN != vector_len*76)
|
|
264 {
|
|
265 fprintf(stderr, "Input and code vector lengths do not match - %d %d\n", vector_len, len);
|
|
266 exit(2);
|
|
267 }
|
|
268 }
|
|
269
|
|
270 sprintf(buf, "%s%c/%s-%c.out", TEST_DIR, law_uc, name, law_uc);
|
|
271 if ((in = open(buf, O_RDONLY)) < 0)
|
|
272 {
|
|
273 fprintf(stderr, "Cannot open %s\n", buf);
|
|
274 exit(2);
|
|
275 }
|
|
276 len = read(in, ref_law_out_vector, 1000000);
|
|
277 close(in);
|
|
278 if (full)
|
|
279 {
|
|
280 if (len != vector_len)
|
|
281 {
|
|
282 fprintf(stderr, "Input and reference vector lengths do not match - %d %d\n", vector_len, len);
|
|
283 exit(2);
|
|
284 }
|
|
285 }
|
|
286 else
|
|
287 {
|
|
288 vector_len = len;
|
|
289 }
|
|
290
|
|
291 sprintf(buf, "%s%c/%s.cod", TEST_DIR, 'L', name);
|
|
292 if ((in = open(buf, O_RDONLY)) < 0)
|
|
293 {
|
|
294 fprintf(stderr, "Cannot open %s\n", buf);
|
|
295 exit(2);
|
|
296 }
|
|
297 len = read(in, code_vector_buf, 1000000);
|
|
298 close(in);
|
|
299 len /= sizeof(int16_t);
|
|
300 for (i = 0; i < len; i++)
|
|
301 decoder_code_vector[i] = code_vector_buf[i];
|
|
302
|
|
303 return len;
|
|
304 }
|
|
305
|
|
306 static int perform_linear_test(int full, int disk, const char *name)
|
|
307 {
|
|
308 gsm0610_state_t *gsm0610_enc_state;
|
|
309 gsm0610_state_t *gsm0610_dec_state;
|
|
310 int i;
|
|
311 int xxx;
|
|
312 int mismatches;
|
|
313
|
|
314 printf("Performing linear test '%s' from disk %d\n", name, disk);
|
|
315
|
|
316 get_test_vector(full, disk, name);
|
|
317
|
|
318 if (full)
|
|
319 {
|
|
320 if ((gsm0610_enc_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
321 {
|
|
322 fprintf(stderr, " Cannot create encoder\n");
|
|
323 exit(2);
|
|
324 }
|
|
325 xxx = gsm0610_encode(gsm0610_enc_state, code_vector, in_vector, vector_len/BLOCK_LEN);
|
|
326
|
|
327 printf("Check code vector of length %d\n", xxx);
|
|
328 for (i = 0, mismatches = 0; i < xxx; i++)
|
|
329 {
|
|
330 if (code_vector[i] != ref_code_vector[i])
|
|
331 {
|
|
332 printf("%8d/%3d: %6d %6d\n", i/76, i%76, code_vector[i], ref_code_vector[i]);
|
|
333 mismatches++;
|
|
334 }
|
|
335 }
|
|
336 gsm0610_release(gsm0610_enc_state);
|
|
337 if (mismatches)
|
|
338 {
|
|
339 printf("Test failed: %d of %d samples mismatch\n", mismatches, xxx);
|
|
340 exit(2);
|
|
341 }
|
|
342 printf("Test passed\n");
|
|
343 }
|
|
344
|
|
345 if ((gsm0610_dec_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
346 {
|
|
347 fprintf(stderr, " Cannot create decoder\n");
|
|
348 exit(2);
|
|
349 }
|
|
350 xxx = gsm0610_decode(gsm0610_dec_state, out_vector, decoder_code_vector, vector_len/BLOCK_LEN);
|
|
351 printf("Check output vector of length %d\n", vector_len);
|
|
352 for (i = 0, mismatches = 0; i < vector_len; i++)
|
|
353 {
|
|
354 if (out_vector[i] != ref_out_vector[i])
|
|
355 {
|
|
356 printf("%8d: %6d %6d\n", i, out_vector[i], ref_out_vector[i]);
|
|
357 mismatches++;
|
|
358 }
|
|
359 }
|
|
360 if (mismatches)
|
|
361 {
|
|
362 printf("Test failed: %d of %d samples mismatch\n", mismatches, vector_len);
|
|
363 exit(2);
|
|
364 }
|
|
365 gsm0610_release(gsm0610_dec_state);
|
|
366 printf("Test passed\n");
|
|
367 return 0;
|
|
368 }
|
|
369
|
|
370 static int perform_law_test(int full, int law, const char *name)
|
|
371 {
|
|
372 gsm0610_state_t *gsm0610_enc_state;
|
|
373 gsm0610_state_t *gsm0610_dec_state;
|
|
374 int i;
|
|
375 int xxx;
|
|
376 int mismatches;
|
|
377
|
|
378 if (law == 'a')
|
|
379 printf("Performing A-law test '%s'\n", name);
|
|
380 else
|
|
381 printf("Performing u-law test '%s'\n", name);
|
|
382
|
|
383 get_law_test_vector(full, law, name);
|
|
384
|
|
385 if (full)
|
|
386 {
|
|
387 if ((gsm0610_enc_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
388 {
|
|
389 fprintf(stderr, " Cannot create encoder\n");
|
|
390 exit(2);
|
|
391 }
|
|
392 if (law == 'a')
|
|
393 {
|
|
394 for (i = 0; i < vector_len; i++)
|
|
395 in_vector[i] = alaw_to_linear(law_in_vector[i]);
|
|
396 }
|
|
397 else
|
|
398 {
|
|
399 for (i = 0; i < vector_len; i++)
|
|
400 in_vector[i] = ulaw_to_linear(law_in_vector[i]);
|
|
401 }
|
|
402 xxx = gsm0610_encode(gsm0610_enc_state, code_vector, in_vector, vector_len/BLOCK_LEN);
|
|
403
|
|
404 printf("Check code vector of length %d\n", xxx);
|
|
405 for (i = 0, mismatches = 0; i < xxx; i++)
|
|
406 {
|
|
407 if (code_vector[i] != ref_code_vector[i])
|
|
408 {
|
|
409 printf("%8d/%3d: %6d %6d %6d\n", i/76, i%76, code_vector[i], ref_code_vector[i], decoder_code_vector[i]);
|
|
410 mismatches++;
|
|
411 }
|
|
412 }
|
|
413 if (mismatches)
|
|
414 {
|
|
415 printf("Test failed: %d of %d samples mismatch\n", mismatches, xxx);
|
|
416 exit(2);
|
|
417 }
|
|
418 printf("Test passed\n");
|
|
419 gsm0610_release(gsm0610_enc_state);
|
|
420 }
|
|
421
|
|
422 if ((gsm0610_dec_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
423 {
|
|
424 fprintf(stderr, " Cannot create decoder\n");
|
|
425 exit(2);
|
|
426 }
|
|
427 xxx = gsm0610_decode(gsm0610_dec_state, out_vector, decoder_code_vector, vector_len/BLOCK_LEN);
|
|
428 if (law == 'a')
|
|
429 {
|
|
430 for (i = 0; i < vector_len; i++)
|
|
431 law_out_vector[i] = linear_to_alaw(out_vector[i]);
|
|
432 }
|
|
433 else
|
|
434 {
|
|
435 for (i = 0; i < vector_len; i++)
|
|
436 law_out_vector[i] = linear_to_ulaw(out_vector[i]);
|
|
437 }
|
|
438 printf("Check output vector of length %d\n", vector_len);
|
|
439 for (i = 0, mismatches = 0; i < vector_len; i++)
|
|
440 {
|
|
441 if (law_out_vector[i] != ref_law_out_vector[i])
|
|
442 {
|
|
443 printf("%8d: %6d %6d\n", i, law_out_vector[i], ref_law_out_vector[i]);
|
|
444 mismatches++;
|
|
445 }
|
|
446 }
|
|
447 if (mismatches)
|
|
448 {
|
|
449 printf("Test failed: %d of %d samples mismatch\n", mismatches, vector_len);
|
|
450 exit(2);
|
|
451 }
|
|
452 gsm0610_release(gsm0610_dec_state);
|
|
453 printf("Test passed\n");
|
|
454 return 0;
|
|
455 }
|
|
456
|
|
457 int main(int argc, char *argv[])
|
|
458 {
|
|
459 AFfilehandle inhandle;
|
|
460 AFfilehandle outhandle;
|
|
461 AFfilesetup filesetup;
|
|
462 int frames;
|
|
463 int outframes;
|
|
464 float x;
|
|
465 int16_t pre_amp[HIST_LEN];
|
|
466 int16_t post_amp[HIST_LEN];
|
|
467 uint8_t gsm0610_data[HIST_LEN];
|
|
468 gsm0610_state_t *gsm0610_enc_state;
|
|
469 gsm0610_state_t *gsm0610_dec_state;
|
|
470 int etsitests;
|
|
471 int packing;
|
|
472 int i;
|
|
473
|
|
474 etsitests = TRUE;
|
|
475 packing = GSM0610_PACKING_NONE;
|
|
476 for (i = 1; i < argc; i++)
|
|
477 {
|
|
478 if (strcmp(argv[i], "-l") == 0)
|
|
479 {
|
|
480 etsitests = FALSE;
|
|
481 continue;
|
|
482 }
|
|
483 if (strcmp(argv[i], "-p") == 0)
|
|
484 {
|
|
485 packing = atoi(argv[++i]);
|
|
486 continue;
|
|
487 }
|
|
488 fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]);
|
|
489 exit(2);
|
|
490 }
|
|
491
|
|
492 if (etsitests)
|
|
493 {
|
|
494 perform_linear_test(TRUE, 1, "Seq01");
|
|
495 perform_linear_test(TRUE, 1, "Seq02");
|
|
496 perform_linear_test(TRUE, 1, "Seq03");
|
|
497 perform_linear_test(TRUE, 1, "Seq04");
|
|
498 perform_linear_test(FALSE, 1, "Seq05");
|
|
499 perform_law_test(TRUE, 'a', "Seq01");
|
|
500 perform_law_test(TRUE, 'a', "Seq02");
|
|
501 perform_law_test(TRUE, 'a', "Seq03");
|
|
502 perform_law_test(TRUE, 'a', "Seq04");
|
|
503 perform_law_test(FALSE, 'a', "Seq05");
|
|
504 perform_law_test(TRUE, 'u', "Seq01");
|
|
505 perform_law_test(TRUE, 'u', "Seq02");
|
|
506 perform_law_test(TRUE, 'u', "Seq03");
|
|
507 perform_law_test(TRUE, 'u', "Seq04");
|
|
508 perform_law_test(FALSE, 'u', "Seq05");
|
|
509
|
|
510 printf("Tests passed.\n");
|
|
511 }
|
|
512 else
|
|
513 {
|
|
514 if ((inhandle = afOpenFile(IN_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE)
|
|
515 {
|
|
516 printf(" Cannot open wave file '%s'\n", IN_FILE_NAME);
|
|
517 exit(2);
|
|
518 }
|
|
519 if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0)
|
|
520 {
|
|
521 printf(" Unexpected frame size in wave file '%s'\n", IN_FILE_NAME);
|
|
522 exit(2);
|
|
523 }
|
|
524 if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE)
|
|
525 {
|
|
526 printf(" Unexpected sample rate in wave file '%s'\n", IN_FILE_NAME);
|
|
527 exit(2);
|
|
528 }
|
|
529 if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0)
|
|
530 {
|
|
531 printf(" Unexpected number of channels in wave file '%s'\n", IN_FILE_NAME);
|
|
532 exit(2);
|
|
533 }
|
|
534 if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
|
|
535 {
|
|
536 fprintf(stderr, " Failed to create file setup\n");
|
|
537 exit(2);
|
|
538 }
|
|
539 afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
|
|
540 afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
|
|
541 afInitFileFormat(filesetup, AF_FILE_WAVE);
|
|
542 afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);
|
|
543
|
|
544 outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup);
|
|
545 if (outhandle == AF_NULL_FILEHANDLE)
|
|
546 {
|
|
547 fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME);
|
|
548 exit(2);
|
|
549 }
|
|
550
|
|
551 if ((gsm0610_enc_state = gsm0610_init(NULL, packing)) == NULL)
|
|
552 {
|
|
553 fprintf(stderr, " Cannot create encoder\n");
|
|
554 exit(2);
|
|
555 }
|
|
556
|
|
557 if ((gsm0610_dec_state = gsm0610_init(NULL, packing)) == NULL)
|
|
558 {
|
|
559 fprintf(stderr, " Cannot create decoder\n");
|
|
560 exit(2);
|
|
561 }
|
|
562
|
|
563 while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, 2*BLOCK_LEN)))
|
|
564 {
|
|
565 gsm0610_encode(gsm0610_enc_state, gsm0610_data, pre_amp, (packing == GSM0610_PACKING_WAV49) ? 1 : 2);
|
|
566 gsm0610_decode(gsm0610_dec_state, post_amp, gsm0610_data, (packing == GSM0610_PACKING_WAV49) ? 1 : 2);
|
|
567 outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_amp, frames);
|
|
568 }
|
|
569
|
|
570 if (afCloseFile(inhandle) != 0)
|
|
571 {
|
|
572 printf(" Cannot close wave file '%s'\n", IN_FILE_NAME);
|
|
573 exit(2);
|
|
574 }
|
|
575 if (afCloseFile(outhandle) != 0)
|
|
576 {
|
|
577 printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME);
|
|
578 exit(2);
|
|
579 }
|
|
580 afFreeFileSetup(filesetup);
|
|
581 gsm0610_release(gsm0610_enc_state);
|
|
582 gsm0610_release(gsm0610_dec_state);
|
|
583 }
|
|
584 return 0;
|
|
585 }
|
|
586 /*- End of function --------------------------------------------------------*/
|
|
587 /*- End of file ------------------------------------------------------------*/
|