Mercurial > hg > audiostuff
comparison spandsp-0.0.3/spandsp-0.0.3/tests/oki_adpcm_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 |
comparison
equal
deleted
inserted
replaced
4:26cd8f1ef0b1 | 5:f762bf195c4b |
---|---|
1 /* | |
2 * SpanDSP - a series of DSP components for telephony | |
3 * | |
4 * oki_adpcm_tests.c - Test the Oki (Dialogic) ADPCM encode and decode | |
5 * software at 24kbps and 32kbps. | |
6 * | |
7 * Written by Steve Underwood <steveu@coppice.org> | |
8 * | |
9 * Copyright (C) 2004 Steve Underwood | |
10 * | |
11 * All rights reserved. | |
12 * | |
13 * This program is free software; you can redistribute it and/or modify | |
14 * it under the terms of the GNU General Public License version 2, as | |
15 * published by the Free Software Foundation. | |
16 * | |
17 * This program is distributed in the hope that it will be useful, | |
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 * GNU General Public License for more details. | |
21 * | |
22 * You should have received a copy of the GNU General Public License | |
23 * along with this program; if not, write to the Free Software | |
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
25 * | |
26 * $Id: oki_adpcm_tests.c,v 1.23 2006/11/19 14:07:27 steveu Exp $ | |
27 */ | |
28 | |
29 /*! \file */ | |
30 | |
31 /*! \page oki_adpcm_tests_page OKI (Dialogic) ADPCM tests | |
32 \section oki_adpcm_tests_page_sec_1 What does it do? | |
33 To perform a general audio quality test, oki_adpcm_tests should be run. The test file | |
34 ../localtests/short_nb_voice.wav will be compressed to the specified bit rate, | |
35 decompressed, and the resulting audio stored in post_oki_adpcm.wav. A simple SNR test | |
36 is automatically performed. Listening tests may be used for a more detailed evaluation | |
37 of the degradation in quality caused by the compression. Both 32k bps and 24k bps | |
38 compression may be tested. | |
39 | |
40 \section oki_adpcm_tests_page_sec_2 How is it used? | |
41 */ | |
42 | |
43 #ifdef HAVE_CONFIG_H | |
44 #include "config.h" | |
45 #endif | |
46 | |
47 #include <stdlib.h> | |
48 #include <inttypes.h> | |
49 #include <string.h> | |
50 #if defined(HAVE_TGMATH_H) | |
51 #include <tgmath.h> | |
52 #endif | |
53 #if defined(HAVE_MATH_H) | |
54 #include <math.h> | |
55 #endif | |
56 #include <stdio.h> | |
57 #include <time.h> | |
58 #include <fcntl.h> | |
59 #include <audiofile.h> | |
60 #include <tiffio.h> | |
61 | |
62 #include "spandsp.h" | |
63 | |
64 #define IN_FILE_NAME "../localtests/short_nb_voice.wav" | |
65 #define OUT_FILE_NAME "post_oki_adpcm.wav" | |
66 | |
67 #define HIST_LEN 1000 | |
68 | |
69 int main(int argc, char *argv[]) | |
70 { | |
71 int i; | |
72 AFfilehandle inhandle; | |
73 AFfilehandle outhandle; | |
74 AFfilesetup filesetup; | |
75 int frames; | |
76 int dec_frames; | |
77 int outframes; | |
78 int oki_bytes; | |
79 int bit_rate; | |
80 float x; | |
81 double pre_energy; | |
82 double post_energy; | |
83 double diff_energy; | |
84 int16_t pre_amp[HIST_LEN]; | |
85 int16_t post_amp[HIST_LEN]; | |
86 uint8_t oki_data[HIST_LEN]; | |
87 int16_t history[HIST_LEN]; | |
88 int hist_in; | |
89 int hist_out; | |
90 oki_adpcm_state_t *oki_enc_state; | |
91 oki_adpcm_state_t *oki_dec_state; | |
92 int xx; | |
93 int total_pre_samples; | |
94 int total_compressed_bytes; | |
95 int total_post_samples; | |
96 const char *in_file_name; | |
97 | |
98 bit_rate = 32000; | |
99 in_file_name = IN_FILE_NAME; | |
100 for (i = 1; i < argc; i++) | |
101 { | |
102 if (strcmp(argv[i], "-2") == 0) | |
103 { | |
104 bit_rate = 24000; | |
105 continue; | |
106 } | |
107 if (strcmp(argv[i], "-i") == 0) | |
108 { | |
109 in_file_name = argv[++i]; | |
110 continue; | |
111 } | |
112 fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]); | |
113 exit(2); | |
114 } | |
115 | |
116 if ((inhandle = afOpenFile(in_file_name, "r", 0)) == AF_NULL_FILEHANDLE) | |
117 { | |
118 printf(" Cannot open wave file '%s'\n", in_file_name); | |
119 exit(2); | |
120 } | |
121 if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0) | |
122 { | |
123 printf(" Unexpected frame size in wave file '%s'\n", in_file_name); | |
124 exit(2); | |
125 } | |
126 if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE) | |
127 { | |
128 printf(" Unexpected sample rate in wave file '%s'\n", in_file_name); | |
129 exit(2); | |
130 } | |
131 if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0) | |
132 { | |
133 printf(" Unexpected number of channels in wave file '%s'\n", in_file_name); | |
134 exit(2); | |
135 } | |
136 if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP) | |
137 { | |
138 fprintf(stderr, " Failed to create file setup\n"); | |
139 exit(2); | |
140 } | |
141 afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16); | |
142 afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE); | |
143 afInitFileFormat(filesetup, AF_FILE_WAVE); | |
144 afInitChannels(filesetup, AF_DEFAULT_TRACK, 1); | |
145 | |
146 outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup); | |
147 if (outhandle == AF_NULL_FILEHANDLE) | |
148 { | |
149 fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME); | |
150 exit(2); | |
151 } | |
152 | |
153 if ((oki_enc_state = oki_adpcm_init(NULL, bit_rate)) == NULL) | |
154 { | |
155 fprintf(stderr, " Cannot create encoder\n"); | |
156 exit(2); | |
157 } | |
158 | |
159 if ((oki_dec_state = oki_adpcm_init(NULL, bit_rate)) == NULL) | |
160 { | |
161 fprintf(stderr, " Cannot create decoder\n"); | |
162 exit(2); | |
163 } | |
164 | |
165 hist_in = 0; | |
166 if (bit_rate == 32000) | |
167 hist_out = 0; | |
168 else | |
169 hist_out = HIST_LEN - 27; | |
170 memset(history, 0, sizeof(history)); | |
171 pre_energy = 0.0; | |
172 post_energy = 0.0; | |
173 diff_energy = 0.0; | |
174 total_pre_samples = 0; | |
175 total_compressed_bytes = 0; | |
176 total_post_samples = 0; | |
177 while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, 159))) | |
178 { | |
179 total_pre_samples +=frames; | |
180 oki_bytes = oki_adpcm_encode(oki_enc_state, oki_data, pre_amp, frames); | |
181 total_compressed_bytes += oki_bytes; | |
182 dec_frames = oki_adpcm_decode(oki_dec_state, post_amp, oki_data, oki_bytes); | |
183 total_post_samples += dec_frames; | |
184 for (i = 0; i < frames; i++) | |
185 { | |
186 history[hist_in++] = pre_amp[i]; | |
187 if (hist_in >= HIST_LEN) | |
188 hist_in = 0; | |
189 pre_energy += (double) pre_amp[i] * (double) pre_amp[i]; | |
190 } | |
191 for (i = 0; i < dec_frames; i++) | |
192 { | |
193 post_energy += (double) post_amp[i] * (double) post_amp[i]; | |
194 xx = post_amp[i] - history[hist_out++]; | |
195 if (hist_out >= HIST_LEN) | |
196 hist_out = 0; | |
197 diff_energy += (double) xx * (double) xx; | |
198 //post_amp[i] = xx; | |
199 } | |
200 outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_amp, dec_frames); | |
201 } | |
202 if (afCloseFile(inhandle) != 0) | |
203 { | |
204 printf(" Cannot close wave file '%s'\n", in_file_name); | |
205 exit(2); | |
206 } | |
207 if (afCloseFile(outhandle) != 0) | |
208 { | |
209 printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME); | |
210 exit(2); | |
211 } | |
212 afFreeFileSetup(filesetup); | |
213 oki_adpcm_release(oki_enc_state); | |
214 oki_adpcm_release(oki_dec_state); | |
215 | |
216 printf("Pre samples: %d\n", total_pre_samples); | |
217 printf("Compressed bytes: %d\n", total_compressed_bytes); | |
218 printf("Post samples: %d\n", total_post_samples); | |
219 | |
220 printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy); | |
221 printf("Residual energy is %f%% of the total.\n", 100.0*diff_energy/post_energy); | |
222 if (bit_rate == 32000) | |
223 { | |
224 if (fabs(1.0 - post_energy/pre_energy) > 0.05 | |
225 || | |
226 fabs(diff_energy/post_energy) > 0.03) | |
227 { | |
228 printf("Tests failed.\n"); | |
229 exit(2); | |
230 } | |
231 } | |
232 else | |
233 { | |
234 if (fabs(1.0 - post_energy/pre_energy) > 0.20 | |
235 || | |
236 fabs(diff_energy/post_energy) > 0.10) | |
237 { | |
238 printf("Tests failed.\n"); | |
239 exit(2); | |
240 } | |
241 } | |
242 | |
243 printf("Tests passed.\n"); | |
244 return 0; | |
245 } | |
246 /*- End of function --------------------------------------------------------*/ | |
247 /*- End of file ------------------------------------------------------------*/ |