2
* SpanDSP - a series of DSP components for telephony
4
* lpc10_tests.c - Test the LPC10 low bit rate speech codec.
6
* Written by Steve Underwood <steveu@coppice.org>
8
* Copyright (C) 2006 Steve Underwood
10
* All rights reserved.
12
* This program is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* (at your option) any later version.
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.
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.
26
* $Id: lpc10_tests.c,v 1.3 2006/09/14 14:45:40 steveu Exp $
31
/*! \page lpc10_tests_page LPC10 codec tests
32
\section lpc10_tests_page_sec_1 What does it do?
34
\section lpc10_tests_page_sec_2 How is it used?
35
To perform a general audio quality test, lpc10 should be run. The file ../localtests/short_nb_voice.wav
36
will be compressed to LPC10 data, decompressed, and the resulting audio stored in post_lpc10.wav.
53
#include <audiofile.h>
60
//#define IN_FILE_NAME "../localtests/short_nb_voice.wav"
61
#define IN_FILE_NAME "../localtests/dam9.wav"
62
#define REF_FILE_NAME "../localtests/dam9_lpc55.wav"
63
#define OUT_FILE_NAME "post_lpc10.wav"
67
static void write_bits(FILE *f, uint8_t bits[], int len)
69
int i; /* generic loop variable */
70
uint8_t mask; /* The next bit position within the variable "data" to place the next bit. */
71
uint8_t data; /* The contents of the next byte to place in the output. */
73
/* Fill in the array bits.
74
* The first compressed output bit will be the most significant
75
* bit of the byte, so initialize mask to 0x80. The next byte of
76
* compressed data is initially 0, and the desired bits will be
81
for (i = 0; i < len; i++)
83
/* Turn on the next bit of output data, if necessary. */
87
* If the byte data is full, determined by mask becoming 0,
88
* then write the byte to the output file, and reinitialize
89
* data and mask for the next output byte. Also add the byte
90
* if (i == len-1), because if len is not a multiple of 8,
91
* then mask won't yet be 0. */
93
if ((mask == 0) || (i == len - 1))
102
int main(int argc, char *argv[])
104
AFfilehandle inhandle;
105
AFfilehandle refhandle;
106
AFfilehandle outhandle;
107
AFfilesetup filesetup;
115
int16_t pre_amp[BLOCK_LEN];
116
int16_t post_amp[BLOCK_LEN];
117
int16_t ref_amp[BLOCK_LEN];
118
int16_t log_amp[BLOCK_LEN*3];
119
uint8_t lpc10_data[BLOCK_LEN];
120
int16_t history[HIST_LEN];
124
lpc10_encode_state_t *lpc10_enc_state;
125
lpc10_decode_state_t *lpc10_dec_state;
132
if (strcmp(argv[i], "-l") == 0)
138
fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]);
143
if ((inhandle = afOpenFile(IN_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE)
145
printf(" Cannot open wave file '%s'\n", IN_FILE_NAME);
148
if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0)
150
printf(" Unexpected frame size in wave file '%s'\n", IN_FILE_NAME);
153
if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE)
155
printf(" Unexpected sample rate in wave file '%s'\n", IN_FILE_NAME);
158
if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0)
160
printf(" Unexpected number of channels in wave file '%s'\n", IN_FILE_NAME);
163
if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
165
fprintf(stderr, " Failed to create file setup\n");
169
if ((refhandle = afOpenFile(REF_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE)
171
printf(" Cannot open wave file '%s'\n", REF_FILE_NAME);
174
if ((x = afGetFrameSize(refhandle, AF_DEFAULT_TRACK, 1)) != 2.0)
176
printf(" Unexpected frame size in wave file '%s'\n", REF_FILE_NAME);
179
if ((x = afGetRate(refhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE)
181
printf(" Unexpected sample rate in wave file '%s'\n", REF_FILE_NAME);
184
if ((x = afGetChannels(refhandle, AF_DEFAULT_TRACK)) != 1.0)
186
printf(" Unexpected number of channels in wave file '%s'\n", REF_FILE_NAME);
190
if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
192
fprintf(stderr, " Failed to create file setup\n");
195
afInitSampleFormat(filesetup, AF_DEFAULT_TRACK, AF_SAMPFMT_TWOSCOMP, 16);
196
afInitRate(filesetup, AF_DEFAULT_TRACK, (float) SAMPLE_RATE);
197
afInitFileFormat(filesetup, AF_FILE_WAVE);
198
afInitChannels(filesetup, AF_DEFAULT_TRACK, 1);
200
if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE)
202
fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME);
206
if ((lpc10_enc_state = lpc10_encode_init(NULL, TRUE)) == NULL)
208
fprintf(stderr, " Cannot create encoder\n");
212
if ((lpc10_dec_state = lpc10_decode_init(NULL, TRUE)) == NULL)
214
fprintf(stderr, " Cannot create decoder\n");
218
memset(history, 0, sizeof(history));
220
hist_out = HIST_LEN - 1100;
226
memset(ref_amp, 0, sizeof(ref_amp));
227
while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, BLOCK_LEN)) == BLOCK_LEN)
229
lpc10_encode(lpc10_enc_state, lpc10_data, pre_amp, 1);
230
//write_bits(stdout, lpc10_data, 54);
231
lpc10_decode(lpc10_dec_state, post_amp, lpc10_data, 1);
232
for (i = 0; i < BLOCK_LEN; i++)
234
pre_energy += (double) pre_amp[i] * (double) pre_amp[i];
235
post_energy += (double) post_amp[i] * (double) post_amp[i];
236
ref_energy += (double) ref_amp[i] * (double) ref_amp[i];
237
/* The reference file has some odd clipping, so eliminate this from the
238
energy measurement. */
239
if (ref_amp[i] == 32767 || ref_amp[i] == -32768)
242
xx = post_amp[i] - ref_amp[i];
243
diff_energy += (double) xx * (double) xx;
244
log_amp[i] = xx; //post_amp[i] - ref_amp[i];
252
x = (char *) &lpc10_dec_state;
253
for (i = 0; i < sizeof(lpc10_decode_state_t); i++)
255
printf("%02x ", x[i] & 0xFF);
263
outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, log_amp, frames);
264
if ((frames = afReadFrames(refhandle, AF_DEFAULT_TRACK, ref_amp, BLOCK_LEN)) != BLOCK_LEN)
268
if (afCloseFile(inhandle) != 0)
270
printf(" Cannot close wave file '%s'\n", IN_FILE_NAME);
273
if (afCloseFile(refhandle) != 0)
275
printf(" Cannot close wave file '%s'\n", REF_FILE_NAME);
278
if (afCloseFile(outhandle) != 0)
280
printf(" Cannot close wave file '%s'\n", OUT_FILE_NAME);
283
afFreeFileSetup(filesetup);
284
lpc10_encode_release(lpc10_enc_state);
285
lpc10_decode_release(lpc10_dec_state);
287
printf("Output energy is %f%% of input energy.\n", 100.0*post_energy/pre_energy);
288
printf("Difference energy is %f%% of the total.\n", 100.0*diff_energy/ref_energy);
289
if (fabs(1.0 - post_energy/pre_energy) > 0.05
291
fabs(diff_energy/post_energy) > 0.03)
293
printf("Tests failed.\n");
297
printf("Tests passed.\n");
300
/*- End of function --------------------------------------------------------*/
301
/*- End of file ------------------------------------------------------------*/