Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/g722_tests.c @ 4:26cd8f1ef0b1
import spandsp-0.0.6pre17
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
|---|---|
| date | Fri, 25 Jun 2010 15:50:58 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 3:c6c5a16ce2f2 | 4:26cd8f1ef0b1 |
|---|---|
| 1 /* | |
| 2 * SpanDSP - a series of DSP components for telephony | |
| 3 * | |
| 4 * g722_tests.c - Test G.722 encode and decode. | |
| 5 * | |
| 6 * Written by Steve Underwood <steveu@coppice.org> | |
| 7 * | |
| 8 * Copyright (C) 2005 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: g722_tests.c,v 1.32 2009/06/02 14:55:36 steveu Exp $ | |
| 26 */ | |
| 27 | |
| 28 /*! \file */ | |
| 29 | |
| 30 /*! \page g722_tests_page G.722 tests | |
| 31 \section g722_tests_page_sec_1 What does it do? | |
| 32 This modules implements two sets of tests: | |
| 33 - The tests defined in the G.722 specification, using the test data files supplied | |
| 34 with 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, 16000 samples/second, and named | |
| 39 "pre_g722.wav". | |
| 40 | |
| 41 The ITU tests use the codec in a special mode, in which the QMFs, which split and recombine the | |
| 42 sub-bands, are disabled. This means they do not test 100% of the codec. This is the reason for | |
| 43 including the additional listening test. | |
| 44 | |
| 45 \section g722_tests_page_sec_2 How is it used? | |
| 46 To perform the tests in the G.722 specification you need to obtain the test data files from the | |
| 47 specification. These are copyright material, and so cannot be distributed with this test software. | |
| 48 | |
| 49 The files, containing test vectors, which are supplied with the G.722 specification, should be | |
| 50 copied to itutests/g722. The ITU tests can then be run by executing g722_tests without | |
| 51 any parameters. | |
| 52 | |
| 53 To perform a general audio quality test, g722_tests should be run with a parameter specifying | |
| 54 the required bit rate for compression. The valid parameters are "-48", "-56", and "-64". | |
| 55 The file ../test-data/local/short_wb_voice.wav will be compressed to the specified bit rate, decompressed, | |
| 56 and the resulting audio stored in post_g722.wav. | |
| 57 */ | |
| 58 | |
| 59 /* Enable the following definition to enable direct probing into the FAX structures */ | |
| 60 //#define WITH_SPANDSP_INTERNALS | |
| 61 | |
| 62 #if defined(HAVE_CONFIG_H) | |
| 63 #include <config.h> | |
| 64 #endif | |
| 65 | |
| 66 #include <stdlib.h> | |
| 67 #include <stdio.h> | |
| 68 #include <fcntl.h> | |
| 69 #include <unistd.h> | |
| 70 #include <memory.h> | |
| 71 #include <ctype.h> | |
| 72 #include <sndfile.h> | |
| 73 | |
| 74 #include "spandsp.h" | |
| 75 | |
| 76 #if 1 //defined(WITH_SPANDSP_INTERNALS) | |
| 77 #include "spandsp/private/g722.h" | |
| 78 #endif | |
| 79 | |
| 80 #define G722_SAMPLE_RATE 16000 | |
| 81 | |
| 82 #define BLOCK_LEN 320 | |
| 83 | |
| 84 #define MAX_TEST_VECTOR_LEN 40000 | |
| 85 | |
| 86 #define TESTDATA_DIR "../test-data/itu/g722/" | |
| 87 | |
| 88 #define EIGHTK_IN_FILE_NAME "../test-data/local/short_nb_voice.wav" | |
| 89 #define IN_FILE_NAME "../test-data/local/short_wb_voice.wav" | |
| 90 #define ENCODED_FILE_NAME "g722.g722" | |
| 91 #define OUT_FILE_NAME "post_g722.wav" | |
| 92 | |
| 93 #if 0 | |
| 94 static const char *itu_test_files[] = | |
| 95 { | |
| 96 TESTDATA_DIR "T1C1.XMT", /* 69973 bytes */ | |
| 97 TESTDATA_DIR "T1C2.XMT", /* 3605 bytes */ | |
| 98 TESTDATA_DIR "T1D3.COD", /* 69973 bytes */ | |
| 99 | |
| 100 TESTDATA_DIR "T2R1.COD", /* 69973 bytes */ | |
| 101 TESTDATA_DIR "T2R2.COD", /* 3605 bytes */ | |
| 102 | |
| 103 TESTDATA_DIR "T3L1.RC1", /* 69973 bytes */ | |
| 104 TESTDATA_DIR "T3L1.RC2", /* 69973 bytes */ | |
| 105 TESTDATA_DIR "T3L1.RC3", /* 69973 bytes */ | |
| 106 TESTDATA_DIR "T3H1.RC0", /* 69973 bytes */ | |
| 107 TESTDATA_DIR "T3L2.RC1", /* 3605 bytes */ | |
| 108 TESTDATA_DIR "T3L2.RC2", /* 3605 bytes */ | |
| 109 TESTDATA_DIR "T3L2.RC3", /* 3605 bytes */ | |
| 110 TESTDATA_DIR "T3H2.RC0", /* 3605 bytes */ | |
| 111 TESTDATA_DIR "T3L3.RC1", /* 69973 bytes */ | |
| 112 TESTDATA_DIR "T3L3.RC2", /* 69973 bytes */ | |
| 113 TESTDATA_DIR "T3L3.RC3", /* 69973 bytes */ | |
| 114 TESTDATA_DIR "T3H3.RC0" /* 69973 bytes */ | |
| 115 }; | |
| 116 #endif | |
| 117 | |
| 118 static const char *encode_test_files[] = | |
| 119 { | |
| 120 TESTDATA_DIR "T1C1.XMT", | |
| 121 TESTDATA_DIR "T2R1.COD", | |
| 122 TESTDATA_DIR "T1C2.XMT", | |
| 123 TESTDATA_DIR "T2R2.COD", | |
| 124 NULL | |
| 125 }; | |
| 126 | |
| 127 static const char *decode_test_files[] = | |
| 128 { | |
| 129 TESTDATA_DIR "T2R1.COD", | |
| 130 TESTDATA_DIR "T3L1.RC1", | |
| 131 TESTDATA_DIR "T3L1.RC2", | |
| 132 TESTDATA_DIR "T3L1.RC3", | |
| 133 TESTDATA_DIR "T3H1.RC0", | |
| 134 | |
| 135 TESTDATA_DIR "T2R2.COD", | |
| 136 TESTDATA_DIR "T3L2.RC1", | |
| 137 TESTDATA_DIR "T3L2.RC2", | |
| 138 TESTDATA_DIR "T3L2.RC3", | |
| 139 TESTDATA_DIR "T3H2.RC0", | |
| 140 | |
| 141 TESTDATA_DIR "T1D3.COD", | |
| 142 TESTDATA_DIR "T3L3.RC1", | |
| 143 TESTDATA_DIR "T3L3.RC2", | |
| 144 TESTDATA_DIR "T3L3.RC3", | |
| 145 TESTDATA_DIR "T3H3.RC0", | |
| 146 | |
| 147 NULL | |
| 148 }; | |
| 149 | |
| 150 int16_t itu_data[MAX_TEST_VECTOR_LEN]; | |
| 151 uint16_t itu_ref[MAX_TEST_VECTOR_LEN]; | |
| 152 uint16_t itu_ref_upper[MAX_TEST_VECTOR_LEN]; | |
| 153 uint8_t compressed[MAX_TEST_VECTOR_LEN]; | |
| 154 int16_t decompressed[MAX_TEST_VECTOR_LEN]; | |
| 155 | |
| 156 static int hex_get(char *s) | |
| 157 { | |
| 158 int i; | |
| 159 int value; | |
| 160 int x; | |
| 161 | |
| 162 for (value = i = 0; i < 4; i++) | |
| 163 { | |
| 164 x = *s++ - 0x30; | |
| 165 if (x > 9) | |
| 166 x -= 0x07; | |
| 167 if (x > 15) | |
| 168 x -= 0x20; | |
| 169 if (x < 0 || x > 15) | |
| 170 return -1; | |
| 171 value <<= 4; | |
| 172 value |= x; | |
| 173 } | |
| 174 return value; | |
| 175 } | |
| 176 /*- End of function --------------------------------------------------------*/ | |
| 177 | |
| 178 static int get_vector(FILE *file, uint16_t vec[]) | |
| 179 { | |
| 180 char buf[132 + 1]; | |
| 181 char *s; | |
| 182 int i; | |
| 183 int value; | |
| 184 | |
| 185 while (fgets(buf, 133, file)) | |
| 186 { | |
| 187 if (buf[0] == '/' && buf[1] == '*') | |
| 188 continue; | |
| 189 s = buf; | |
| 190 i = 0; | |
| 191 while ((value = hex_get(s)) >= 0) | |
| 192 { | |
| 193 vec[i++] = value; | |
| 194 s += 4; | |
| 195 } | |
| 196 return i; | |
| 197 } | |
| 198 return 0; | |
| 199 } | |
| 200 /*- End of function --------------------------------------------------------*/ | |
| 201 | |
| 202 static int get_test_vector(const char *file, uint16_t buf[], int max_len) | |
| 203 { | |
| 204 int octets; | |
| 205 int i; | |
| 206 FILE *infile; | |
| 207 | |
| 208 if ((infile = fopen(file, "r")) == NULL) | |
| 209 { | |
| 210 fprintf(stderr, " Failed to open '%s'\n", file); | |
| 211 exit(2); | |
| 212 } | |
| 213 octets = 0; | |
| 214 while ((i = get_vector(infile, buf + octets)) > 0) | |
| 215 octets += i; | |
| 216 fclose(infile); | |
| 217 return octets; | |
| 218 } | |
| 219 /*- End of function --------------------------------------------------------*/ | |
| 220 | |
| 221 static void itu_compliance_tests(void) | |
| 222 { | |
| 223 g722_encode_state_t enc_state; | |
| 224 g722_decode_state_t dec_state; | |
| 225 int i; | |
| 226 int j; | |
| 227 int k; | |
| 228 int len_comp; | |
| 229 int len_comp_upper; | |
| 230 int len_data; | |
| 231 int len; | |
| 232 int len2; | |
| 233 int mode; | |
| 234 int file; | |
| 235 | |
| 236 #if 1 | |
| 237 /* ITU G.722 encode tests, using configuration 1. The QMF is bypassed */ | |
| 238 for (file = 0; encode_test_files[file]; file += 2) | |
| 239 { | |
| 240 printf("Testing %s -> %s\n", encode_test_files[file], encode_test_files[file + 1]); | |
| 241 | |
| 242 /* Get the input data */ | |
| 243 len_data = get_test_vector(encode_test_files[file], (uint16_t *) itu_data, MAX_TEST_VECTOR_LEN); | |
| 244 | |
| 245 /* Get the reference output data */ | |
| 246 len_comp = get_test_vector(encode_test_files[file + 1], itu_ref, MAX_TEST_VECTOR_LEN); | |
| 247 | |
| 248 /* Process the input data */ | |
| 249 /* Skip the reset stuff at each end of the data */ | |
| 250 for (i = 0; i < len_data; i++) | |
| 251 { | |
| 252 if ((itu_data[i] & 1) == 0) | |
| 253 break; | |
| 254 } | |
| 255 for (j = i; j < len_data; j++) | |
| 256 { | |
| 257 if ((itu_data[j] & 1)) | |
| 258 break; | |
| 259 } | |
| 260 len = j - i; | |
| 261 g722_encode_init(&enc_state, 64000, 0); | |
| 262 enc_state.itu_test_mode = TRUE; | |
| 263 len2 = g722_encode(&enc_state, compressed, itu_data + i, len); | |
| 264 | |
| 265 /* Check the result against the ITU's reference output data */ | |
| 266 j = 0; | |
| 267 for (k = 0; k < len2; k++) | |
| 268 { | |
| 269 if ((compressed[k] & 0xFF) != ((itu_ref[k + i] >> 8) & 0xFF)) | |
| 270 { | |
| 271 printf(">>> %6d %4x %4x\n", k, compressed[k] & 0xFF, itu_ref[k + i] & 0xFFFF); | |
| 272 j++; | |
| 273 } | |
| 274 } | |
| 275 printf("%d bad samples, out of %d/%d samples\n", j, len, len_data); | |
| 276 if (j) | |
| 277 { | |
| 278 printf("Test failed\n"); | |
| 279 exit(2); | |
| 280 } | |
| 281 printf("Test passed\n"); | |
| 282 } | |
| 283 #endif | |
| 284 #if 1 | |
| 285 /* ITU G.722 decode tests, using configuration 2. The QMF is bypassed */ | |
| 286 /* Run each of the tests for each of the modes - 48kbps, 56kbps and 64kbps. */ | |
| 287 for (mode = 1; mode <= 3; mode++) | |
| 288 { | |
| 289 for (file = 0; decode_test_files[file]; file += 5) | |
| 290 { | |
| 291 printf("Testing mode %d, %s -> %s + %s\n", | |
| 292 mode, | |
| 293 decode_test_files[file], | |
| 294 decode_test_files[file + mode], | |
| 295 decode_test_files[file + 4]); | |
| 296 | |
| 297 /* Get the input data */ | |
| 298 len_data = get_test_vector(decode_test_files[file], (uint16_t *) itu_data, MAX_TEST_VECTOR_LEN); | |
| 299 | |
| 300 /* Get the lower reference output data */ | |
| 301 len_comp = get_test_vector(decode_test_files[file + mode], itu_ref, MAX_TEST_VECTOR_LEN); | |
| 302 | |
| 303 /* Get the upper reference output data */ | |
| 304 len_comp_upper = get_test_vector(decode_test_files[file + 4], itu_ref_upper, MAX_TEST_VECTOR_LEN); | |
| 305 | |
| 306 /* Process the input data */ | |
| 307 /* Skip the reset stuff at each end of the data */ | |
| 308 for (i = 0; i < len_data; i++) | |
| 309 { | |
| 310 if ((itu_data[i] & 1) == 0) | |
| 311 break; | |
| 312 } | |
| 313 for (j = i; j < len_data; j++) | |
| 314 { | |
| 315 if ((itu_data[j] & 1)) | |
| 316 break; | |
| 317 } | |
| 318 len = j - i; | |
| 319 for (k = 0; k < len; k++) | |
| 320 compressed[k] = itu_data[k + i] >> ((mode == 3) ? 10 : (mode == 2) ? 9 : 8); | |
| 321 | |
| 322 g722_decode_init(&dec_state, (mode == 3) ? 48000 : (mode == 2) ? 56000 : 64000, 0); | |
| 323 dec_state.itu_test_mode = TRUE; | |
| 324 len2 = g722_decode(&dec_state, decompressed, compressed, len); | |
| 325 | |
| 326 /* Check the result against the ITU's reference output data */ | |
| 327 j = 0; | |
| 328 for (k = 0; k < len2; k += 2) | |
| 329 { | |
| 330 if ((decompressed[k] & 0xFFFF) != (itu_ref[(k >> 1) + i] & 0xFFFF) | |
| 331 || | |
| 332 (decompressed[k + 1] & 0xFFFF) != (itu_ref_upper[(k >> 1) + i] & 0xFFFF)) | |
| 333 { | |
| 334 printf(">>> %6d %4x %4x %4x %4x\n", k >> 1, decompressed[k] & 0xFFFF, decompressed[k + 1] & 0xFFFF, itu_ref[(k >> 1) + i] & 0xFFFF, itu_ref_upper[(k >> 1) + i] & 0xFFFF); | |
| 335 j++; | |
| 336 } | |
| 337 } | |
| 338 printf("%d bad samples, out of %d/%d samples\n", j, len, len_data); | |
| 339 if (j) | |
| 340 { | |
| 341 printf("Test failed\n"); | |
| 342 exit(2); | |
| 343 } | |
| 344 printf("Test passed\n"); | |
| 345 } | |
| 346 } | |
| 347 #endif | |
| 348 printf("Tests passed.\n"); | |
| 349 } | |
| 350 /*- End of function --------------------------------------------------------*/ | |
| 351 | |
| 352 int main(int argc, char *argv[]) | |
| 353 { | |
| 354 g722_encode_state_t enc_state; | |
| 355 g722_decode_state_t dec_state; | |
| 356 int len2; | |
| 357 int len3; | |
| 358 int i; | |
| 359 int file; | |
| 360 SNDFILE *inhandle; | |
| 361 SNDFILE *outhandle; | |
| 362 SF_INFO info; | |
| 363 int outframes; | |
| 364 int samples; | |
| 365 int opt; | |
| 366 int itutests; | |
| 367 int bit_rate; | |
| 368 int eight_k_in; | |
| 369 int eight_k_out; | |
| 370 int encode; | |
| 371 int decode; | |
| 372 int tone_test; | |
| 373 const char *in_file; | |
| 374 const char *out_file; | |
| 375 int16_t indata[BLOCK_LEN]; | |
| 376 int16_t outdata[BLOCK_LEN]; | |
| 377 uint8_t adpcmdata[BLOCK_LEN]; | |
| 378 float tone_level; | |
| 379 uint32_t tone_phase; | |
| 380 int32_t tone_phase_rate; | |
| 381 | |
| 382 bit_rate = 64000; | |
| 383 eight_k_in = FALSE; | |
| 384 eight_k_out = FALSE; | |
| 385 itutests = TRUE; | |
| 386 encode = FALSE; | |
| 387 decode = FALSE; | |
| 388 tone_test = FALSE; | |
| 389 in_file = NULL; | |
| 390 out_file = NULL; | |
| 391 while ((opt = getopt(argc, argv, "b:d:e:i:l:o:t")) != -1) | |
| 392 { | |
| 393 switch (opt) | |
| 394 { | |
| 395 case 'b': | |
| 396 bit_rate = atoi(optarg); | |
| 397 if (bit_rate != 48000 && bit_rate != 56000 && bit_rate != 64000) | |
| 398 { | |
| 399 fprintf(stderr, "Invalid bit rate selected. Only 48000, 56000 and 64000 are valid.\n"); | |
| 400 exit(2); | |
| 401 } | |
| 402 itutests = FALSE; | |
| 403 break; | |
| 404 case 'd': | |
| 405 in_file = optarg; | |
| 406 decode = TRUE; | |
| 407 itutests = FALSE; | |
| 408 break; | |
| 409 case 'e': | |
| 410 in_file = optarg; | |
| 411 encode = TRUE; | |
| 412 itutests = FALSE; | |
| 413 break; | |
| 414 case 'i': | |
| 415 i = atoi(optarg); | |
| 416 if (i != 8000 && i != 16000) | |
| 417 { | |
| 418 fprintf(stderr, "Invalid incoming sample rate. Only 8000 and 16000 are valid.\n"); | |
| 419 exit(2); | |
| 420 } | |
| 421 eight_k_in = (i == 8000); | |
| 422 if (eight_k_in) | |
| 423 in_file = EIGHTK_IN_FILE_NAME; | |
| 424 break; | |
| 425 case 'l': | |
| 426 out_file = optarg; | |
| 427 break; | |
| 428 case 'o': | |
| 429 i = atoi(optarg); | |
| 430 if (i != 8000 && i != 16000) | |
| 431 { | |
| 432 fprintf(stderr, "Invalid outgoing sample rate. Only 8000 and 16000 are valid.\n"); | |
| 433 exit(2); | |
| 434 } | |
| 435 eight_k_out = (i == 8000); | |
| 436 break; | |
| 437 case 't': | |
| 438 tone_test = TRUE; | |
| 439 itutests = FALSE; | |
| 440 break; | |
| 441 default: | |
| 442 //usage(); | |
| 443 exit(2); | |
| 444 } | |
| 445 } | |
| 446 | |
| 447 if (itutests) | |
| 448 { | |
| 449 itu_compliance_tests(); | |
| 450 } | |
| 451 else | |
| 452 { | |
| 453 tone_level = dds_scaling_dbm0f(2.5f); | |
| 454 tone_phase = 0; | |
| 455 tone_phase_rate = dds_phase_ratef(1500.0f/2.0f); | |
| 456 if (!decode && !encode) | |
| 457 { | |
| 458 decode = | |
| 459 encode = TRUE; | |
| 460 } | |
| 461 if (in_file == NULL) | |
| 462 { | |
| 463 if (encode) | |
| 464 { | |
| 465 if (eight_k_in) | |
| 466 in_file = EIGHTK_IN_FILE_NAME; | |
| 467 else | |
| 468 in_file = IN_FILE_NAME; | |
| 469 } | |
| 470 else | |
| 471 { | |
| 472 in_file = ENCODED_FILE_NAME; | |
| 473 } | |
| 474 } | |
| 475 if (out_file == NULL) | |
| 476 { | |
| 477 out_file = (decode) ? OUT_FILE_NAME : ENCODED_FILE_NAME; | |
| 478 } | |
| 479 inhandle = NULL; | |
| 480 outhandle = NULL; | |
| 481 file = -1; | |
| 482 if (encode) | |
| 483 { | |
| 484 if (eight_k_in) | |
| 485 { | |
| 486 if ((inhandle = sf_open(in_file, SFM_READ, &info)) == NULL) | |
| 487 { | |
| 488 fprintf(stderr, " Cannot open audio file '%s'\n", in_file); | |
| 489 exit(2); | |
| 490 } | |
| 491 if (info.samplerate != SAMPLE_RATE) | |
| 492 { | |
| 493 fprintf(stderr, " Unexpected sample rate %d in audio file '%s'\n", info.samplerate, in_file); | |
| 494 exit(2); | |
| 495 } | |
| 496 if (info.channels != 1) | |
| 497 { | |
| 498 fprintf(stderr, " Unexpected number of channels in audio file '%s'\n", in_file); | |
| 499 exit(2); | |
| 500 } | |
| 501 } | |
| 502 else | |
| 503 { | |
| 504 if ((inhandle = sf_open(in_file, SFM_READ, &info)) == NULL) | |
| 505 { | |
| 506 fprintf(stderr, " Cannot open audio file '%s'\n", in_file); | |
| 507 exit(2); | |
| 508 } | |
| 509 if (info.samplerate != G722_SAMPLE_RATE) | |
| 510 { | |
| 511 fprintf(stderr, " Unexpected sample rate %d in audio file '%s'\n", info.samplerate, in_file); | |
| 512 exit(2); | |
| 513 } | |
| 514 if (info.channels != 1) | |
| 515 { | |
| 516 fprintf(stderr, " Unexpected number of channels in audio file '%s'\n", in_file); | |
| 517 exit(2); | |
| 518 } | |
| 519 } | |
| 520 if (eight_k_in) | |
| 521 g722_encode_init(&enc_state, bit_rate, G722_PACKED | G722_SAMPLE_RATE_8000); | |
| 522 else | |
| 523 g722_encode_init(&enc_state, bit_rate, G722_PACKED); | |
| 524 } | |
| 525 else | |
| 526 { | |
| 527 if ((file = open(in_file, O_RDONLY)) < 0) | |
| 528 { | |
| 529 fprintf(stderr, " Failed to open '%s'\n", in_file); | |
| 530 exit(2); | |
| 531 } | |
| 532 } | |
| 533 if (decode) | |
| 534 { | |
| 535 memset(&info, 0, sizeof(info)); | |
| 536 info.frames = 0; | |
| 537 info.samplerate = (eight_k_out) ? SAMPLE_RATE : G722_SAMPLE_RATE; | |
| 538 info.channels = 1; | |
| 539 info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16; | |
| 540 info.sections = 1; | |
| 541 info.seekable = 1; | |
| 542 if ((outhandle = sf_open(out_file, SFM_WRITE, &info)) == NULL) | |
| 543 { | |
| 544 fprintf(stderr, " Cannot create audio file '%s'\n", out_file); | |
| 545 exit(2); | |
| 546 } | |
| 547 if (eight_k_out) | |
| 548 g722_decode_init(&dec_state, bit_rate, G722_PACKED | G722_SAMPLE_RATE_8000); | |
| 549 else | |
| 550 g722_decode_init(&dec_state, bit_rate, G722_PACKED); | |
| 551 } | |
| 552 else | |
| 553 { | |
| 554 if ((file = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) | |
| 555 { | |
| 556 fprintf(stderr, " Failed to open '%s'\n", out_file); | |
| 557 exit(2); | |
| 558 } | |
| 559 } | |
| 560 for (;;) | |
| 561 { | |
| 562 if (encode) | |
| 563 { | |
| 564 samples = sf_readf_short(inhandle, indata, BLOCK_LEN); | |
| 565 if (samples <= 0) | |
| 566 break; | |
| 567 if (tone_test) | |
| 568 { | |
| 569 for (i = 0; i < samples; i++) | |
| 570 indata[i] = dds_modf(&tone_phase, tone_phase_rate, tone_level, 0); | |
| 571 } | |
| 572 len2 = g722_encode(&enc_state, adpcmdata, indata, samples); | |
| 573 } | |
| 574 else | |
| 575 { | |
| 576 len2 = read(file, adpcmdata, BLOCK_LEN); | |
| 577 if (len2 <= 0) | |
| 578 break; | |
| 579 } | |
| 580 if (decode) | |
| 581 { | |
| 582 len3 = g722_decode(&dec_state, outdata, adpcmdata, len2); | |
| 583 outframes = sf_writef_short(outhandle, outdata, len3); | |
| 584 if (outframes != len3) | |
| 585 { | |
| 586 fprintf(stderr, " Error writing audio file\n"); | |
| 587 exit(2); | |
| 588 } | |
| 589 } | |
| 590 else | |
| 591 { | |
| 592 len3 = write(file, adpcmdata, len2); | |
| 593 if (len3 <= 0) | |
| 594 break; | |
| 595 } | |
| 596 } | |
| 597 if (encode) | |
| 598 { | |
| 599 if (sf_close(inhandle)) | |
| 600 { | |
| 601 fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME); | |
| 602 exit(2); | |
| 603 } | |
| 604 } | |
| 605 else | |
| 606 { | |
| 607 close(file); | |
| 608 } | |
| 609 if (decode) | |
| 610 { | |
| 611 if (sf_close(outhandle)) | |
| 612 { | |
| 613 fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME); | |
| 614 exit(2); | |
| 615 } | |
| 616 } | |
| 617 else | |
| 618 { | |
| 619 close(file); | |
| 620 } | |
| 621 printf("'%s' translated to '%s' at %dbps.\n", in_file, out_file, bit_rate); | |
| 622 } | |
| 623 return 0; | |
| 624 } | |
| 625 /*- End of function --------------------------------------------------------*/ | |
| 626 /*- End of file ------------------------------------------------------------*/ |
