Mercurial > hg > audiostuff
diff spandsp-0.0.3/spandsp-0.0.3/tests/g726_tests.c @ 5:f762bf195c4b
import spandsp-0.0.3
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:00:21 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spandsp-0.0.3/spandsp-0.0.3/tests/g726_tests.c Fri Jun 25 16:00:21 2010 +0200 @@ -0,0 +1,1343 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * g726_tests.c - Test G.726 encode and decode. + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2006 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id: g726_tests.c,v 1.16 2006/11/19 14:07:27 steveu Exp $ + */ + +/*! \file */ + +/*! \page g726_tests_page G.726 tests +\section g726_tests_page_sec_1 What does it do? +Two sets of tests are performed: + - The tests defined in the G.726 specification, using the test data files supplied with + the specification. + - A generally audio quality test, consisting of compressing and decompressing a speeech + file for audible comparison. + +The speech file should be recorded at 16 bits/sample, 8000 samples/second, and named +"pre_g726.wav". + +\section g726_tests_page_sec_2 How is it used? +To perform the tests in the G.726 specification you need to obtain the test data files from the +specification. These are copyright material, and so cannot be distributed with spandsp. + +The files, containing test vectors, which are supplied with the G.726 specification, should be +copied to itutests/g726 so the files are arranged in the same directory heirarchy in which they +are supplied. That is, you should have file names like + + - itutests/g726/DISK1/INPUT/NRM.M + - itutests/g726/DISK1/INPUT/OVR.M + - itutests/g726/DISK2/INPUT/NRM.A + - itutests/g726/DISK2/INPUT/OVR.A + +in your spandsp source tree. The ITU tests can then be run by executing g726_tests without +any parameters. + +To perform a general audio quality test, g726_tests should be run with a parameter specifying +the required bit rate for compression. The valid parameters are "-16", "-24", "-32", and "-40". +The test file ../localtests/short_nb_voice.wav will be compressed to the specified bit rate, +decompressed, and the resulting audio stored in post_g726.wav. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <inttypes.h> +#include <memory.h> +#include <stdlib.h> +#if defined(HAVE_TGMATH_H) +#include <tgmath.h> +#endif +#if defined(HAVE_MATH_H) +#include <math.h> +#endif +#include <audiofile.h> +#include <ctype.h> +#include <tiffio.h> + +#include "spandsp.h" + +#define BLOCK_LEN 320 +#define MAX_TEST_VECTOR_LEN 40000 + +#define IN_FILE_NAME "../localtests/short_nb_voice.wav" +#define OUT_FILE_NAME "post_g726.wav" + +#define TESTDATA_DIR "../itutests/g726/" + +int16_t outdata[MAX_TEST_VECTOR_LEN]; +uint8_t adpcmdata[MAX_TEST_VECTOR_LEN]; + +int16_t itudata[MAX_TEST_VECTOR_LEN]; +uint8_t itu_ref[MAX_TEST_VECTOR_LEN]; +uint8_t unpacked[MAX_TEST_VECTOR_LEN]; +uint8_t xlaw[MAX_TEST_VECTOR_LEN]; + +/* +Table 4 - V Reset and homing sequences for u-law + Normal I-input Overload +Algorithm Input Intermediate Output Input Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) + +16F NRM.M RN16FM.I RN16FM.O I16 RI16FM.O OVR.M RV16FM.I RV16FM.O + HN16FM.I HN16FM.O HI16FM.O HV16FM.I HV16FM.O + +24F NRM.M RN24FM.I RN24FM.O I24 RI24FM.O OVR.M RV24FM.I RV24FM.O + HN24FM.I HN24FM.O HI24FM.O HV24FM.I HV24FM.O + +32F NRM.M RN32FM.I RN32FM.O I32 RI32FM.O OVR.M RV32FM.I RV32FM.O + HN32FM.I HN32FM.O HI32FM.O HV32FM.I HV32FM.O + +40F NRM.M RN40FM.I RN40FM.O I40 RI40FM.O OVR.M RV40FM.I RV40FM.O + HN40FM.I HN40FM.O HI40FM.O HV40FM.I HV40FM.O + + +Table 5 - V Reset and homing sequences for A-law + Normal I-input Overload +Algorithm Input Intermediate Output Input Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) +16F NRM.A RN16FA.I RN16FA.O I16 RI16FA.O OVR.A RV16FA.I RV16FA.O + HN16FA.I HN16FA.O HI16FA.O HV16FA.I HV16FA.O + +24F NRM.A RN24FA.I RN24FA.O I24 RI24FA.O OVR.A RV24FA.I RV24FA.O + HN24FA.I HN24FA.O HI24FA.O HV24FA.I HV24FA.O + +32F NRM.A RN32FA.I RN32FA.O I32 RI32FA.O OVR.A RV32FA.I RV32FA.O + HN32FA.I HN32FA.O HI32FA.O HV32FA.I HV32FA.O + +40F NRM.A RN40FA.I RN40FA.O I40 RI40FA.O OVR.A RV40FA.I RV40FA.O + HN40FA.I HN40FA.O HI40FA.O HV40FA.I HV40FA.O + +Table 6 ¡V Reset and homing cross sequences for u-law -> A-law + Normal Overload +Algorithm Input Intermediate Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) +16F NRM.M RN16FM.I RN16FC.O OVR.M RV16FM.I RV16FC.O + HN16FM.I HN16FC.O HV16FM.I HV16FC.O + +24F NRM.M RN24FM.I RN24FC.O OVR.M RV24FM.I RV24FC.O + HN24FM.I HN24FC.O HV24FM.I HV24FC.O + +32F NRM.M RN32FM.I RN32FC.O OVR.M RV32FM.I RV32FC.O + HN32FM.I HN32FC.O HV32FM.I HV32FC.O + +40F NRM.M RN40FM.I RN40FC.O OVR.M RV40FM.I RV40FC.O + HN40FM.I HN40FC.O HV40FM.I HV40FC.O + +Table 7 ¡V Reset and homing cross sequences for A-law -> u-law + Normal Overload +Algorithm Input Intermediate Output Input Intermediate Output + (PCM) (ADPCM) (PCM) (PCM) (ADPCM) (PCM) +16F NRM.A RN16FA.I RN16FX.O OVR.A RV16FA.I RV16FX.O + HN16FA.I HN16FX.O HV16FA.I HV16FX.O + +24F NRM.A RN24FA.I RN24FX.O OVR.A RV24FA.I RV24FX.O + HN24FA.I HN24FX.O HV24FA.I HV24FX.O + +32F NRM.A RN32FA.I RN32FX.O OVR.A RV32FA.I RV32FX.O + HN32FA.I HN32FX.O HV32FA.I HV32FX.O + +40F NRM.A RN40FA.I RN40FX.O OVR.A RV40FA.I RV40FX.O + HN40FA.I HN40FX.O HV40FA.I HV40FX.O +*/ + +#define G726_ENCODING_NONE 9999 + +typedef struct +{ + const char *conditioning_pcm_file; + const char *pcm_file; + const char *conditioning_adpcm_file; + const char *adpcm_file; + const char *output_file; + int rate; + int compression_law; + int decompression_law; +} test_set_t; + +static test_set_t itu_test_sets[] = +{ + /* u-law to u-law tests */ + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RN16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RN16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I16", + TESTDATA_DIR "DISK1/RESET/16/RI16FM.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RV16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RV16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RN24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RN24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I24", + TESTDATA_DIR "DISK1/RESET/24/RI24FM.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RV24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RV24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RN32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RN32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I32", + TESTDATA_DIR "DISK1/RESET/32/RI32FM.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RV32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RV32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RN40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RN40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK1/INPUT/I40", + TESTDATA_DIR "DISK1/RESET/40/RI40FM.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RV40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RV40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + /* A-law to A-law tests */ + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RN16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RN16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I16", + TESTDATA_DIR "DISK2/RESET/16/RI16FA.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RV16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RV16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RN24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RN24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I24", + TESTDATA_DIR "DISK2/RESET/24/RI24FA.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RV24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RV24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RN32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RN32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I32", + TESTDATA_DIR "DISK2/RESET/32/RI32FA.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RV32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RV32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RN40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RN40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + "", + TESTDATA_DIR "DISK2/INPUT/I40", + TESTDATA_DIR "DISK2/RESET/40/RI40FA.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RV40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RV40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + /* u-law to A-law tests */ + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RN16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RN16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/16/RV16FM.I", + TESTDATA_DIR "DISK1/RESET/16/RV16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RN24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RN24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/24/RV24FM.I", + TESTDATA_DIR "DISK1/RESET/24/RV24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RN32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RN32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/32/RV32FM.I", + TESTDATA_DIR "DISK1/RESET/32/RV32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RN40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RN40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + "", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + "", + TESTDATA_DIR "DISK1/RESET/40/RV40FM.I", + TESTDATA_DIR "DISK1/RESET/40/RV40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + /* A-law to u-law tests */ + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RN16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RN16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/16/RV16FA.I", + TESTDATA_DIR "DISK2/RESET/16/RV16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RN24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RN24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/24/RV24FA.I", + TESTDATA_DIR "DISK2/RESET/24/RV24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RN32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RN32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/32/RV32FA.I", + TESTDATA_DIR "DISK2/RESET/32/RV32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RN40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RN40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + "", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + "", + TESTDATA_DIR "DISK2/RESET/40/RV40FA.I", + TESTDATA_DIR "DISK2/RESET/40/RV40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + /* u-law to u-law tests */ + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK1/HOMING/16/HN16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HN16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK1/INPUT/I16", + TESTDATA_DIR "DISK1/HOMING/16/HI16FM.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK1/HOMING/16/HV16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HV16FM.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK1/HOMING/24/HN24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HN24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK1/INPUT/I24", + TESTDATA_DIR "DISK1/HOMING/24/HI24FM.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK1/HOMING/24/HV24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HV24FM.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK1/HOMING/32/HN32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HN32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK1/INPUT/I32", + TESTDATA_DIR "DISK1/HOMING/32/HI32FM.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK1/HOMING/32/HV32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HV32FM.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK1/HOMING/40/HN40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HN40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + { + "", + "", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK1/INPUT/I40", + TESTDATA_DIR "DISK1/HOMING/40/HI40FM.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK1/HOMING/40/HV40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HV40FM.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ULAW + }, + /* A-law to A-law tests */ + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK2/HOMING/16/HN16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HN16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK2/INPUT/I16", + TESTDATA_DIR "DISK2/HOMING/16/HI16FA.O", + 16000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK2/HOMING/16/HV16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HV16FA.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK2/HOMING/24/HN24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HN24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK2/INPUT/I24", + TESTDATA_DIR "DISK2/HOMING/24/HI24FA.O", + 24000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK2/HOMING/24/HV24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HV24FA.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK2/HOMING/32/HN32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HN32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK2/INPUT/I32", + TESTDATA_DIR "DISK2/HOMING/32/HI32FA.O", + 32000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK2/HOMING/32/HV32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HV32FA.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK2/HOMING/40/HN40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HN40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + { + "", + "", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK2/INPUT/I40", + TESTDATA_DIR "DISK2/HOMING/40/HI40FA.O", + 40000, + G726_ENCODING_NONE, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK2/HOMING/40/HV40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HV40FA.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ALAW + }, + /* u-law to A-law tests */ + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK1/HOMING/16/HN16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HN16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/16/I_INI_16.A", + TESTDATA_DIR "DISK1/HOMING/16/HV16FM.I", + TESTDATA_DIR "DISK1/HOMING/16/HV16FC.O", + 16000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK1/HOMING/24/HN24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HN24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/24/I_INI_24.A", + TESTDATA_DIR "DISK1/HOMING/24/HV24FM.I", + TESTDATA_DIR "DISK1/HOMING/24/HV24FC.O", + 24000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK1/HOMING/32/HN32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HN32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/32/I_INI_32.A", + TESTDATA_DIR "DISK1/HOMING/32/HV32FM.I", + TESTDATA_DIR "DISK1/HOMING/32/HV32FC.O", + 32000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/NRM.M", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK1/HOMING/40/HN40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HN40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + { + TESTDATA_DIR "DISK1/PCM_INIT.M", + TESTDATA_DIR "DISK1/INPUT/OVR.M", + TESTDATA_DIR "DISK2/HOMING/40/I_INI_40.A", + TESTDATA_DIR "DISK1/HOMING/40/HV40FM.I", + TESTDATA_DIR "DISK1/HOMING/40/HV40FC.O", + 40000, + G726_ENCODING_ULAW, + G726_ENCODING_ALAW + }, + /* A-law to u-law tests */ + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK2/HOMING/16/HN16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HN16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/16/I_INI_16.M", + TESTDATA_DIR "DISK2/HOMING/16/HV16FA.I", + TESTDATA_DIR "DISK2/HOMING/16/HV16FX.O", + 16000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK2/HOMING/24/HN24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HN24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/24/I_INI_24.M", + TESTDATA_DIR "DISK2/HOMING/24/HV24FA.I", + TESTDATA_DIR "DISK2/HOMING/24/HV24FX.O", + 24000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK2/HOMING/32/HN32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HN32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/32/I_INI_32.M", + TESTDATA_DIR "DISK2/HOMING/32/HV32FA.I", + TESTDATA_DIR "DISK2/HOMING/32/HV32FX.O", + 32000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/NRM.A", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK2/HOMING/40/HN40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HN40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + TESTDATA_DIR "DISK2/PCM_INIT.A", + TESTDATA_DIR "DISK2/INPUT/OVR.A", + TESTDATA_DIR "DISK1/HOMING/40/I_INI_40.M", + TESTDATA_DIR "DISK2/HOMING/40/HV40FA.I", + TESTDATA_DIR "DISK2/HOMING/40/HV40FX.O", + 40000, + G726_ENCODING_ALAW, + G726_ENCODING_ULAW + }, + { + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0 + } +}; + +static int hex_get(char *s) +{ + int i; + int value; + int x; + + for (value = i = 0; i < 2; i++) + { + x = *s++ - 0x30; + if (x > 9) + x -= 0x07; + if (x > 15) + x -= 0x20; + if (x < 0 || x > 15) + return -1; + value <<= 4; + value |= x; + } + return value; +} +/*- End of function --------------------------------------------------------*/ + +static int get_vector(FILE *file, uint8_t vec[]) +{ + char buf[132 + 1]; + char *s; + int i; + int value; + + while (fgets(buf, 133, file)) + { + s = buf; + i = 0; + while ((value = hex_get(s)) >= 0) + { + vec[i++] = value; + s += 2; + } + return i; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int get_test_vector(const char *file, uint8_t buf[], int max_len) +{ + int octets; + int i; + int sum; + FILE *infile; + + if ((infile = fopen(file, "r")) == NULL) + { + fprintf(stderr, " Failed to open '%s'\n", file); + exit(2); + } + octets = 0; + while ((i = get_vector(infile, buf + octets)) > 0) + octets += i; + fclose(infile); + /* The last octet is a sumcheck, so the real data octets are one less than + the total we have */ + octets--; + /* Test the checksum */ + for (sum = i = 0; i < octets; i++) + sum += buf[i]; + if (sum%255 != (int) buf[i]) + { + fprintf(stderr, " Sumcheck failed in '%s' - %x %x\n", file, sum%255, buf[i]); + exit(2); + } + return octets; +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + g726_state_t enc_state; + g726_state_t dec_state; + int len2; + int len3; + int i; + int test; + int bits_per_code; + int itutests; + int bit_rate; + int bad_samples; + AFfilehandle inhandle; + AFfilehandle outhandle; + AFfilesetup filesetup; + int16_t amp[1024]; + int frames; + int outframes; + int conditioning_samples; + int samples; + int conditioning_adpcm; + int adpcm; + int packing; + float x; + + i = 1; + bit_rate = 32000; + itutests = TRUE; + packing = G726_PACKING_NONE; + while (argc > i) + { + if (strcmp(argv[i], "-16") == 0) + { + bit_rate = 16000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-24") == 0) + { + bit_rate = 24000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-32") == 0) + { + bit_rate = 32000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-40") == 0) + { + bit_rate = 40000; + itutests = FALSE; + i++; + } + else if (strcmp(argv[i], "-l") == 0) + { + packing = G726_PACKING_LEFT; + i++; + } + else if (strcmp(argv[i], "-r") == 0) + { + packing = G726_PACKING_RIGHT; + i++; + } + else + { + fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]); + exit(2); + } + } + + len2 = 0; + conditioning_samples = 0; + if (itutests) + { + for (test = 0; itu_test_sets[test].rate; test++) + { + printf("Test %2d: '%s' + '%s'\n" + " -> '%s' + '%s'\n" + " -> '%s' [%d, %d, %d]\n", + test, + itu_test_sets[test].conditioning_pcm_file, + itu_test_sets[test].pcm_file, + itu_test_sets[test].conditioning_adpcm_file, + itu_test_sets[test].adpcm_file, + itu_test_sets[test].output_file, + itu_test_sets[test].rate, + itu_test_sets[test].compression_law, + itu_test_sets[test].decompression_law); + switch (itu_test_sets[test].rate) + { + case 16000: + bits_per_code = 2; + break; + case 24000: + bits_per_code = 3; + break; + case 32000: + default: + bits_per_code = 4; + break; + case 40000: + bits_per_code = 5; + break; + } + if (itu_test_sets[test].compression_law != G726_ENCODING_NONE) + { + /* Test the encode side */ + g726_init(&enc_state, itu_test_sets[test].rate, itu_test_sets[test].compression_law, G726_PACKING_NONE); + if (itu_test_sets[test].conditioning_pcm_file[0]) + { + conditioning_samples = get_test_vector(itu_test_sets[test].conditioning_pcm_file, xlaw, MAX_TEST_VECTOR_LEN); + printf("Test %d: Homing %d samples at %dbps\n", test, conditioning_samples, itu_test_sets[test].rate); + } + else + { + conditioning_samples = 0; + } + samples = get_test_vector(itu_test_sets[test].pcm_file, xlaw + conditioning_samples, MAX_TEST_VECTOR_LEN); + memcpy(itudata, xlaw, samples + conditioning_samples); + printf("Test %d: Compressing %d samples at %dbps\n", test, samples, itu_test_sets[test].rate); + len2 = g726_encode(&enc_state, adpcmdata, itudata, conditioning_samples + samples); + } + /* Test the decode side */ + g726_init(&dec_state, itu_test_sets[test].rate, itu_test_sets[test].decompression_law, G726_PACKING_NONE); + if (itu_test_sets[test].conditioning_adpcm_file[0]) + { + conditioning_adpcm = get_test_vector(itu_test_sets[test].conditioning_adpcm_file, unpacked, MAX_TEST_VECTOR_LEN); + printf("Test %d: Homing %d octets at %dbps\n", test, conditioning_adpcm, itu_test_sets[test].rate); + } + else + { + conditioning_adpcm = 0; + } + adpcm = get_test_vector(itu_test_sets[test].adpcm_file, unpacked + conditioning_adpcm, MAX_TEST_VECTOR_LEN); + if (itu_test_sets[test].compression_law != G726_ENCODING_NONE) + { + /* Test our compressed version against the reference compressed version */ + printf("Test %d: Compressed data check - %d/%d octets\n", test, conditioning_adpcm + adpcm, len2); + if (conditioning_adpcm + adpcm == len2) + { + for (bad_samples = 0, i = conditioning_samples; i < len2; i++) + { + if (adpcmdata[i] != unpacked[i]) + { + bad_samples++; + printf("Test %d: Compressed mismatch %d %x %x\n", test, i, adpcmdata[i], unpacked[i]); + } + } + if (bad_samples > 0) + { + printf("Test failed\n"); + exit(2); + } + printf("Test passed\n"); + } + else + { + printf("Test %d: Length mismatch - ref = %d, processed = %d\n", test, conditioning_adpcm + adpcm, len2); + exit(2); + } + } + + len3 = g726_decode(&dec_state, outdata, unpacked, conditioning_adpcm + adpcm); + + /* Get the output reference data */ + samples = get_test_vector(itu_test_sets[test].output_file, xlaw, MAX_TEST_VECTOR_LEN); + memcpy(itu_ref, xlaw, samples); + /* Test our decompressed version against the reference decompressed version */ + printf("Test %d: Decompressed data check - %d/%d samples\n", test, samples, len3 - conditioning_adpcm); + if (samples == len3 - conditioning_adpcm) + { + for (bad_samples = 0, i = 0; i < len3; i++) + { + if (itu_ref[i] != ((uint8_t *) outdata)[i + conditioning_adpcm]) + { + bad_samples++; + printf("Test %d: Decompressed mismatch %d %x %x\n", test, i, itu_ref[i], ((uint8_t *) outdata)[i + conditioning_adpcm]); + } + } + if (bad_samples > 0) + { + printf("Test failed\n"); + exit(2); + } + printf("Test passed\n"); + } + else + { + printf("Test %d: Length mismatch - ref = %d, processed = %d\n", test, samples, len3 - conditioning_adpcm); + exit(2); + } + } + + printf("Tests passed.\n"); + } + else + { + if ((inhandle = afOpenFile(IN_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE) + { + printf(" Cannot open wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) + { + printf(" Unexpected frame size in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) + { + printf(" Unexpected sample rate in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) + { + printf(" Unexpected number of channels in wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) + { + fprintf(stderr, " Failed to create file setup\n"); + exit(2); + } + afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); + afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); + afInitFileFormat(filesetup, AF_FILE_WAVE); + afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); + + outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup); + if (outhandle == AF_NULL_FILEHANDLE) + { + fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + + printf("ADPCM packing is %d\n", packing); + g726_init(&enc_state, bit_rate, G726_ENCODING_LINEAR, packing); + g726_init(&dec_state, bit_rate, G726_ENCODING_LINEAR, packing); + + while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, amp, 159))) + { + adpcm = g726_encode(&enc_state, adpcmdata, amp, frames); + frames = g726_decode(&dec_state, amp, adpcmdata, adpcm); + outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, amp, frames); + } + if (afCloseFile(inhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", IN_FILE_NAME); + exit(2); + } + if (afCloseFile(outhandle) != 0) + { + printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME); + exit(2); + } + afFreeFileSetup(filesetup); + printf("'%s' transcoded to '%s' at %dbps.\n", IN_FILE_NAME, OUT_FILE_NAME, bit_rate); + } + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/