~ubuntu-branches/ubuntu/saucy/iaxmodem/saucy

« back to all changes in this revision

Viewing changes to lib/spandsp/tests/lpc10_tests.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien BLACHE
  • Date: 2006-10-28 10:54:55 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20061028105455-qdnaih9tmq0uc29w
Tags: 0.1.15~dfsg-1
* New upstream release.
* debian/rules:
  + Use new ~dfsg versionning scheme.
  + Do not remove config.* in get-orig-source.
* debian/patches/11_build_configure-stamp.dpatch:
  + Updated.
* debian/iaxmodem.init:
  + Added LSB header.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SpanDSP - a series of DSP components for telephony
 
3
 *
 
4
 * lpc10_tests.c - Test the LPC10 low bit rate speech 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 as published by
 
14
 * the Free Software Foundation; either version 2 of the License, or
 
15
 * (at your option) any later version.
 
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: lpc10_tests.c,v 1.3 2006/09/14 14:45:40 steveu Exp $
 
27
 */
 
28
 
 
29
/*! \file */
 
30
 
 
31
/*! \page lpc10_tests_page LPC10 codec tests
 
32
\section lpc10_tests_page_sec_1 What does it do?
 
33
 
 
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.
 
37
*/
 
38
 
 
39
#ifdef HAVE_CONFIG_H
 
40
#include "config.h"
 
41
#endif
 
42
 
 
43
#include <inttypes.h>
 
44
#include <stdlib.h>
 
45
#include <unistd.h>
 
46
#include <stdio.h>
 
47
#include <string.h>
 
48
#include <math.h>
 
49
#include <assert.h>
 
50
#include <fcntl.h>
 
51
#include <ctype.h>
 
52
#include <stdio.h>
 
53
#include <audiofile.h>
 
54
#include <tiffio.h>
 
55
 
 
56
#include "spandsp.h"
 
57
 
 
58
#define BLOCK_LEN       180
 
59
 
 
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"
 
64
 
 
65
#define HIST_LEN        2000
 
66
 
 
67
static void write_bits(FILE *f, uint8_t bits[], int len)
 
68
{
 
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. */
 
72
 
 
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
 
77
     * turned on below.
 
78
     */
 
79
    mask = 0x80;
 
80
    data = 0;
 
81
    for (i = 0;  i < len;  i++)
 
82
    {
 
83
        /* Turn on the next bit of output data, if necessary. */
 
84
        if (bits[i])
 
85
            data |= mask;
 
86
        /*
 
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.  */
 
92
        mask >>= 1;
 
93
        if ((mask == 0)  ||  (i == len - 1))
 
94
        {
 
95
            putc(data, f);
 
96
            data = 0;
 
97
            mask = 0x80;
 
98
        }
 
99
    }
 
100
}
 
101
 
 
102
int main(int argc, char *argv[])
 
103
{
 
104
    AFfilehandle inhandle;
 
105
    AFfilehandle refhandle;
 
106
    AFfilehandle outhandle;
 
107
    AFfilesetup filesetup;
 
108
    int frames;
 
109
    int outframes;
 
110
    float x;
 
111
    double pre_energy;
 
112
    double post_energy;
 
113
    double ref_energy;
 
114
    double diff_energy;
 
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];
 
121
    int hist_in;
 
122
    int hist_out;
 
123
    double xx;
 
124
    lpc10_encode_state_t *lpc10_enc_state;
 
125
    lpc10_decode_state_t *lpc10_dec_state;
 
126
    int i;
 
127
    int block_no;
 
128
 
 
129
    i = 1;
 
130
    while (argc > i)
 
131
    {
 
132
        if (strcmp(argv[i], "-l") == 0)
 
133
        {
 
134
            i++;
 
135
        }
 
136
        else
 
137
        {
 
138
            fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]);
 
139
            exit(2);
 
140
        }
 
141
    }
 
142
 
 
143
    if ((inhandle = afOpenFile(IN_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE)
 
144
    {
 
145
        printf("    Cannot open wave file '%s'\n", IN_FILE_NAME);
 
146
        exit(2);
 
147
    }
 
148
    if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0)
 
149
    {
 
150
        printf("    Unexpected frame size in wave file '%s'\n", IN_FILE_NAME);
 
151
        exit(2);
 
152
    }
 
153
    if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE)
 
154
    {
 
155
        printf("    Unexpected sample rate in wave file '%s'\n", IN_FILE_NAME);
 
156
        exit(2);
 
157
    }
 
158
    if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0)
 
159
    {
 
160
        printf("    Unexpected number of channels in wave file '%s'\n", IN_FILE_NAME);
 
161
        exit(2);
 
162
    }
 
163
    if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
 
164
    {
 
165
        fprintf(stderr, "    Failed to create file setup\n");
 
166
        exit(2);
 
167
    }
 
168
 
 
169
    if ((refhandle = afOpenFile(REF_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE)
 
170
    {
 
171
        printf("    Cannot open wave file '%s'\n", REF_FILE_NAME);
 
172
        exit(2);
 
173
    }
 
174
    if ((x = afGetFrameSize(refhandle, AF_DEFAULT_TRACK, 1)) != 2.0)
 
175
    {
 
176
        printf("    Unexpected frame size in wave file '%s'\n", REF_FILE_NAME);
 
177
        exit(2);
 
178
    }
 
179
    if ((x = afGetRate(refhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE)
 
180
    {
 
181
        printf("    Unexpected sample rate in wave file '%s'\n", REF_FILE_NAME);
 
182
        exit(2);
 
183
    }
 
184
    if ((x = afGetChannels(refhandle, AF_DEFAULT_TRACK)) != 1.0)
 
185
    {
 
186
        printf("    Unexpected number of channels in wave file '%s'\n", REF_FILE_NAME);
 
187
        exit(2);
 
188
    }
 
189
 
 
190
    if ((filesetup = afNewFileSetup()) == AF_NULL_FILESETUP)
 
191
    {
 
192
        fprintf(stderr, "    Failed to create file setup\n");
 
193
        exit(2);
 
194
    }
 
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);
 
199
 
 
200
    if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE)
 
201
    {
 
202
        fprintf(stderr, "    Cannot create wave file '%s'\n", OUT_FILE_NAME);
 
203
        exit(2);
 
204
    }
 
205
    
 
206
    if ((lpc10_enc_state = lpc10_encode_init(NULL, TRUE)) == NULL)
 
207
    {
 
208
        fprintf(stderr, "    Cannot create encoder\n");
 
209
        exit(2);
 
210
    }
 
211
            
 
212
    if ((lpc10_dec_state = lpc10_decode_init(NULL, TRUE)) == NULL)
 
213
    {
 
214
        fprintf(stderr, "    Cannot create decoder\n");
 
215
        exit(2);
 
216
    }
 
217
 
 
218
    memset(history, 0, sizeof(history));
 
219
    hist_in = 0;
 
220
    hist_out = HIST_LEN - 1100;
 
221
    pre_energy = 0.0;
 
222
    post_energy = 0.0;
 
223
    ref_energy = 0.0;
 
224
    diff_energy = 0.0;
 
225
    block_no = 0;
 
226
    memset(ref_amp, 0, sizeof(ref_amp));
 
227
    while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, BLOCK_LEN)) == BLOCK_LEN)
 
228
    {
 
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++)
 
233
        {
 
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)
 
240
                xx = 0.0;
 
241
            else
 
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];
 
245
        }
 
246
        block_no++;
 
247
#if 0
 
248
{
 
249
    int i;
 
250
    char *x;
 
251
    
 
252
    x = (char *) &lpc10_dec_state;
 
253
    for (i = 0;  i < sizeof(lpc10_decode_state_t);  i++)
 
254
    {
 
255
        printf("%02x ", x[i] & 0xFF);
 
256
        if ((i & 15) == 15)
 
257
            printf("\n");
 
258
    }
 
259
    printf("\n");
 
260
    exit(2);
 
261
}
 
262
#endif
 
263
        outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, log_amp, frames);
 
264
        if ((frames = afReadFrames(refhandle, AF_DEFAULT_TRACK, ref_amp, BLOCK_LEN)) != BLOCK_LEN)
 
265
            break;
 
266
    }
 
267
 
 
268
    if (afCloseFile(inhandle) != 0)
 
269
    {
 
270
        printf("    Cannot close wave file '%s'\n", IN_FILE_NAME);
 
271
        exit(2);
 
272
    }
 
273
    if (afCloseFile(refhandle) != 0)
 
274
    {
 
275
        printf("    Cannot close wave file '%s'\n", REF_FILE_NAME);
 
276
        exit(2);
 
277
    }
 
278
    if (afCloseFile(outhandle) != 0)
 
279
    {
 
280
        printf("    Cannot close wave file '%s'\n", OUT_FILE_NAME);
 
281
        exit(2);
 
282
    }
 
283
    afFreeFileSetup(filesetup);
 
284
    lpc10_encode_release(lpc10_enc_state);
 
285
    lpc10_decode_release(lpc10_dec_state);
 
286
 
 
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
 
290
        ||
 
291
        fabs(diff_energy/post_energy) > 0.03)
 
292
    {
 
293
        printf("Tests failed.\n");
 
294
        exit(2);
 
295
    }
 
296
    
 
297
    printf("Tests passed.\n");
 
298
    return 0;
 
299
}
 
300
/*- End of function --------------------------------------------------------*/
 
301
/*- End of file ------------------------------------------------------------*/