forked from Mirrors/freeswitch
0f27549c48
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7544 d0543943-73ff-0310-b7d9-9358b9ac24b2
650 lines
20 KiB
C
650 lines
20 KiB
C
/*
|
|
* VoIPcodecs - a series of DSP components for telephony
|
|
*
|
|
* gsm0610_tests.c - Test the GSM 06.10 FR codec.
|
|
*
|
|
* 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: gsm0610_tests.c,v 1.8 2007/11/10 11:14:58 steveu Exp $
|
|
*/
|
|
|
|
/*! \file */
|
|
|
|
/*! \page gsm0610_tests_page GSM 06.10 full rate codec tests
|
|
\section gsm0610_tests_page_sec_1 What does it do?
|
|
Two sets of tests are performed:
|
|
- The tests defined in the GSM 06.10 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_gsm0610.wav".
|
|
|
|
\section gsm0610_tests_page_sec_2 How is it used?
|
|
To perform the tests in the GSM 06.10 specification you need to obtain the test data files from the
|
|
specification. These are copyright material, and so cannot be distributed with this test software.
|
|
They can, however, be freely downloaded from the ETSI web site.
|
|
|
|
The files, containing test vectors, which are supplied with the GSM 06.10 specification, should be
|
|
copied to etsitests/gsm0610/unpacked so the files are arranged in the following directories.
|
|
|
|
./fr_A:
|
|
Seq01-A.cod Seq01-A.inp Seq01-A.out
|
|
Seq02-A.cod Seq02-A.inp Seq02-A.out
|
|
Seq03-A.cod Seq03-A.inp Seq03-A.out
|
|
Seq04-A.cod Seq04-A.inp Seq04-A.out
|
|
Seq05-A.out
|
|
|
|
./fr_L:
|
|
Seq01.cod Seq01.inp Seq01.out
|
|
Seq02.cod Seq02.inp Seq02.out
|
|
Seq03.cod Seq03.inp Seq03.out
|
|
Seq04.cod Seq04.inp Seq04.out
|
|
Seq05.cod Seq05.out
|
|
|
|
./fr_U:
|
|
Seq01-U.cod Seq01-U.inp Seq01-U.out
|
|
Seq02-U.cod Seq02-U.inp Seq02-U.out
|
|
Seq03-U.cod Seq03-U.inp Seq03-U.out
|
|
Seq04-U.cod Seq04-U.inp Seq04-U.out
|
|
Seq05-U.out
|
|
|
|
./fr_homing_A:
|
|
Homing01_A.out
|
|
Seq01H_A.cod Seq01H_A.inp Seq01H_A.out
|
|
Seq02H_A.cod Seq02H_A.inp Seq02H_A.out
|
|
Seq03H_A.cod Seq03H_A.inp Seq03H_A.out
|
|
Seq04H_A.cod Seq04H_A.inp Seq04H_A.out
|
|
Seq05H_A.out
|
|
Seq06H_A.cod Seq06H_A.inp
|
|
|
|
./fr_homing_L:
|
|
Homing01.cod Homing01.out
|
|
Seq01h.cod Seq01h.inp Seq01h.out
|
|
Seq02h.cod Seq02h.inp Seq02h.out
|
|
Seq03h.cod Seq03h.inp Seq03h.out
|
|
Seq04h.cod Seq04h.inp Seq04h.out
|
|
Seq05h.cod Seq05h.out
|
|
Seq06h.cod Seq06h.inp
|
|
|
|
./fr_homing_U:
|
|
Homing01_U.out
|
|
Seq01H_U.cod Seq01H_U.inp Seq01H_U.out
|
|
Seq02H_U.cod Seq02H_U.inp Seq02H_U.out
|
|
Seq03H_U.cod Seq03H_U.inp Seq03H_U.out
|
|
Seq04H_U.cod Seq04H_U.inp Seq04H_U.out
|
|
Seq05H_U.out
|
|
Seq06H_U.cod Seq06H_U.inp
|
|
|
|
./fr_sync_A:
|
|
Seqsync_A.inp
|
|
Sync000_A.cod --to-- Sync159_A.cod
|
|
|
|
./fr_sync_L:
|
|
Bitsync.inp
|
|
Seqsync.inp
|
|
Sync000.cod --to-- Sync159.cod
|
|
|
|
./fr_sync_U:
|
|
Seqsync_U.inp
|
|
Sync000_U.cod --to-- Sync159_U.cod
|
|
|
|
This is different from the directory structure in which they are supplied. Also, the files names are a little
|
|
different. The supplied names are messy, and inconsistent across the sets. The names required by these tests
|
|
just clean up these inconsistencies. Note that you will need a Windows machine to unpack some of the supplied
|
|
files.
|
|
|
|
To perform a general audio quality test, gsm0610_tests should be run. The file ../localtests/short_nb_voice.wav
|
|
will be compressed to GSM 06.10 data, decompressed, and the resulting audio stored in post_gsm0610.wav.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <audiofile.h>
|
|
|
|
#include "voipcodecs.h"
|
|
|
|
#define BLOCK_LEN 160
|
|
|
|
#define TEST_DIR "../etsitests/gsm0610/unpacked/fr_"
|
|
|
|
#define IN_FILE_NAME "../localtests/short_nb_voice.wav"
|
|
#define OUT_FILE_NAME "post_gsm0610.wav"
|
|
|
|
#define HIST_LEN 1000
|
|
|
|
uint8_t law_in_vector[1000000];
|
|
int16_t in_vector[1000000];
|
|
uint16_t code_vector_buf[1000000];
|
|
uint8_t code_vector[1000000];
|
|
uint8_t ref_code_vector[1000000];
|
|
uint8_t decoder_code_vector[1000000];
|
|
uint8_t law_out_vector[1000000];
|
|
int16_t out_vector[1000000];
|
|
int16_t ref_out_vector[1000000];
|
|
uint8_t ref_law_out_vector[1000000];
|
|
int vector_len;
|
|
|
|
static int get_test_vector(int full, int disk, const char *name)
|
|
{
|
|
char buf[500];
|
|
int in;
|
|
int len;
|
|
int i;
|
|
|
|
if (full)
|
|
{
|
|
sprintf(buf, "%s%c/%s.inp", TEST_DIR, 'L', name);
|
|
if ((in = open(buf, O_RDONLY)) < 0)
|
|
{
|
|
fprintf(stderr, "Cannot open %s\n", buf);
|
|
exit(2);
|
|
}
|
|
len = read(in, in_vector, 1000000);
|
|
close(in);
|
|
len /= sizeof(int16_t);
|
|
vector_len = len;
|
|
}
|
|
|
|
sprintf(buf, "%s%c/%s.out", TEST_DIR, 'L', name);
|
|
if ((in = open(buf, O_RDONLY)) < 0)
|
|
{
|
|
fprintf(stderr, "Cannot open %s\n", buf);
|
|
exit(2);
|
|
}
|
|
len = read(in, ref_out_vector, 1000000);
|
|
close(in);
|
|
len /= sizeof(int16_t);
|
|
if (full)
|
|
{
|
|
if (len != vector_len)
|
|
{
|
|
fprintf(stderr, "Input and reference vector lengths do not match - %d %d\n", vector_len, len);
|
|
exit(2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vector_len = len;
|
|
}
|
|
|
|
sprintf(buf, "%s%c/%s.cod", TEST_DIR, 'L', name);
|
|
if ((in = open(buf, O_RDONLY)) < 0)
|
|
{
|
|
fprintf(stderr, "Cannot open %s\n", buf);
|
|
exit(2);
|
|
}
|
|
len = read(in, code_vector_buf, 1000000);
|
|
close(in);
|
|
len /= sizeof(int16_t);
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
ref_code_vector[i] = code_vector_buf[i];
|
|
decoder_code_vector[i] = code_vector_buf[i];
|
|
}
|
|
if (len*BLOCK_LEN != vector_len*76)
|
|
{
|
|
fprintf(stderr, "Input and code vector lengths do not match - %d %d\n", vector_len, len);
|
|
exit(2);
|
|
}
|
|
|
|
return len;
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
static int get_law_test_vector(int full, int law, const char *name)
|
|
{
|
|
char buf[500];
|
|
int in;
|
|
int len;
|
|
int i;
|
|
int law_uc;
|
|
|
|
law_uc = toupper(law);
|
|
|
|
if (full)
|
|
{
|
|
sprintf(buf, "%s%c/%s-%c.inp", TEST_DIR, law_uc, name, law_uc);
|
|
if ((in = open(buf, O_RDONLY)) < 0)
|
|
{
|
|
fprintf(stderr, "Cannot open %s\n", buf);
|
|
exit(2);
|
|
}
|
|
len = read(in, law_in_vector, 1000000);
|
|
close(in);
|
|
vector_len = len;
|
|
|
|
sprintf(buf, "%s%c/%s-%c.cod", TEST_DIR, law_uc, name, law_uc);
|
|
if ((in = open(buf, O_RDONLY)) < 0)
|
|
{
|
|
fprintf(stderr, "Cannot open %s\n", buf);
|
|
exit(2);
|
|
}
|
|
len = read(in, code_vector_buf, 1000000);
|
|
close(in);
|
|
len /= sizeof(int16_t);
|
|
for (i = 0; i < len; i++)
|
|
ref_code_vector[i] = code_vector_buf[i];
|
|
if (len*BLOCK_LEN != vector_len*76)
|
|
{
|
|
fprintf(stderr, "Input and code vector lengths do not match - %d %d\n", vector_len, len);
|
|
exit(2);
|
|
}
|
|
}
|
|
|
|
sprintf(buf, "%s%c/%s-%c.out", TEST_DIR, law_uc, name, law_uc);
|
|
if ((in = open(buf, O_RDONLY)) < 0)
|
|
{
|
|
fprintf(stderr, "Cannot open %s\n", buf);
|
|
exit(2);
|
|
}
|
|
len = read(in, ref_law_out_vector, 1000000);
|
|
close(in);
|
|
if (full)
|
|
{
|
|
if (len != vector_len)
|
|
{
|
|
fprintf(stderr, "Input and reference vector lengths do not match - %d %d\n", vector_len, len);
|
|
exit(2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vector_len = len;
|
|
}
|
|
|
|
sprintf(buf, "%s%c/%s.cod", TEST_DIR, 'L', name);
|
|
if ((in = open(buf, O_RDONLY)) < 0)
|
|
{
|
|
fprintf(stderr, "Cannot open %s\n", buf);
|
|
exit(2);
|
|
}
|
|
len = read(in, code_vector_buf, 1000000);
|
|
close(in);
|
|
len /= sizeof(int16_t);
|
|
for (i = 0; i < len; i++)
|
|
decoder_code_vector[i] = code_vector_buf[i];
|
|
|
|
return len;
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
static int perform_linear_test(int full, int disk, const char *name)
|
|
{
|
|
gsm0610_state_t *gsm0610_enc_state;
|
|
gsm0610_state_t *gsm0610_dec_state;
|
|
int i;
|
|
int xxx;
|
|
int mismatches;
|
|
|
|
printf("Performing linear test '%s' from disk %d\n", name, disk);
|
|
|
|
get_test_vector(full, disk, name);
|
|
|
|
if (full)
|
|
{
|
|
if ((gsm0610_enc_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
{
|
|
fprintf(stderr, " Cannot create encoder\n");
|
|
exit(2);
|
|
}
|
|
xxx = gsm0610_encode(gsm0610_enc_state, code_vector, in_vector, vector_len/BLOCK_LEN);
|
|
|
|
printf("Check code vector of length %d\n", xxx);
|
|
for (i = 0, mismatches = 0; i < xxx; i++)
|
|
{
|
|
if (code_vector[i] != ref_code_vector[i])
|
|
{
|
|
printf("%8d/%3d: %6d %6d\n", i/76, i%76, code_vector[i], ref_code_vector[i]);
|
|
mismatches++;
|
|
}
|
|
}
|
|
gsm0610_release(gsm0610_enc_state);
|
|
if (mismatches)
|
|
{
|
|
printf("Test failed: %d of %d samples mismatch\n", mismatches, xxx);
|
|
exit(2);
|
|
}
|
|
printf("Test passed\n");
|
|
}
|
|
|
|
if ((gsm0610_dec_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
{
|
|
fprintf(stderr, " Cannot create decoder\n");
|
|
exit(2);
|
|
}
|
|
xxx = gsm0610_decode(gsm0610_dec_state, out_vector, decoder_code_vector, vector_len/BLOCK_LEN);
|
|
printf("Check output vector of length %d\n", vector_len);
|
|
for (i = 0, mismatches = 0; i < vector_len; i++)
|
|
{
|
|
if (out_vector[i] != ref_out_vector[i])
|
|
{
|
|
printf("%8d: %6d %6d\n", i, out_vector[i], ref_out_vector[i]);
|
|
mismatches++;
|
|
}
|
|
}
|
|
if (mismatches)
|
|
{
|
|
printf("Test failed: %d of %d samples mismatch\n", mismatches, vector_len);
|
|
exit(2);
|
|
}
|
|
gsm0610_release(gsm0610_dec_state);
|
|
printf("Test passed\n");
|
|
return 0;
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
static int perform_law_test(int full, int law, const char *name)
|
|
{
|
|
gsm0610_state_t *gsm0610_enc_state;
|
|
gsm0610_state_t *gsm0610_dec_state;
|
|
int i;
|
|
int xxx;
|
|
int mismatches;
|
|
|
|
if (law == 'a')
|
|
printf("Performing A-law test '%s'\n", name);
|
|
else
|
|
printf("Performing u-law test '%s'\n", name);
|
|
|
|
get_law_test_vector(full, law, name);
|
|
|
|
if (full)
|
|
{
|
|
if ((gsm0610_enc_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
{
|
|
fprintf(stderr, " Cannot create encoder\n");
|
|
exit(2);
|
|
}
|
|
if (law == 'a')
|
|
{
|
|
for (i = 0; i < vector_len; i++)
|
|
in_vector[i] = alaw_to_linear(law_in_vector[i]);
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < vector_len; i++)
|
|
in_vector[i] = ulaw_to_linear(law_in_vector[i]);
|
|
}
|
|
xxx = gsm0610_encode(gsm0610_enc_state, code_vector, in_vector, vector_len/BLOCK_LEN);
|
|
|
|
printf("Check code vector of length %d\n", xxx);
|
|
for (i = 0, mismatches = 0; i < xxx; i++)
|
|
{
|
|
if (code_vector[i] != ref_code_vector[i])
|
|
{
|
|
printf("%8d/%3d: %6d %6d %6d\n", i/76, i%76, code_vector[i], ref_code_vector[i], decoder_code_vector[i]);
|
|
mismatches++;
|
|
}
|
|
}
|
|
if (mismatches)
|
|
{
|
|
printf("Test failed: %d of %d samples mismatch\n", mismatches, xxx);
|
|
exit(2);
|
|
}
|
|
printf("Test passed\n");
|
|
gsm0610_release(gsm0610_enc_state);
|
|
}
|
|
|
|
if ((gsm0610_dec_state = gsm0610_init(NULL, GSM0610_PACKING_NONE)) == NULL)
|
|
{
|
|
fprintf(stderr, " Cannot create decoder\n");
|
|
exit(2);
|
|
}
|
|
xxx = gsm0610_decode(gsm0610_dec_state, out_vector, decoder_code_vector, vector_len/BLOCK_LEN);
|
|
if (law == 'a')
|
|
{
|
|
for (i = 0; i < vector_len; i++)
|
|
law_out_vector[i] = linear_to_alaw(out_vector[i]);
|
|
}
|
|
else
|
|
{
|
|
for (i = 0; i < vector_len; i++)
|
|
law_out_vector[i] = linear_to_ulaw(out_vector[i]);
|
|
}
|
|
printf("Check output vector of length %d\n", vector_len);
|
|
for (i = 0, mismatches = 0; i < vector_len; i++)
|
|
{
|
|
if (law_out_vector[i] != ref_law_out_vector[i])
|
|
{
|
|
printf("%8d: %6d %6d\n", i, law_out_vector[i], ref_law_out_vector[i]);
|
|
mismatches++;
|
|
}
|
|
}
|
|
if (mismatches)
|
|
{
|
|
printf("Test failed: %d of %d samples mismatch\n", mismatches, vector_len);
|
|
exit(2);
|
|
}
|
|
gsm0610_release(gsm0610_dec_state);
|
|
printf("Test passed\n");
|
|
return 0;
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
static int repack_gsm0610_voip_to_wav49(uint8_t c[], const uint8_t d[])
|
|
{
|
|
gsm0610_frame_t frame[2];
|
|
int n;
|
|
|
|
n = gsm0610_unpack_voip(&frame[0], d);
|
|
gsm0610_unpack_voip(&frame[1], d + n);
|
|
n = gsm0610_pack_wav49(c, frame);
|
|
return n;
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
static int repack_gsm0610_wav49_to_voip(uint8_t d[], const uint8_t c[])
|
|
{
|
|
gsm0610_frame_t frame[2];
|
|
int n[2];
|
|
|
|
gsm0610_unpack_wav49(frame, c);
|
|
n[0] = gsm0610_pack_voip(d, &frame[0]);
|
|
n[1] = gsm0610_pack_voip(d + n[0], &frame[1]);
|
|
return n[0] + n[1];
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
static int perform_pack_unpack_test(void)
|
|
{
|
|
uint8_t a[66];
|
|
uint8_t b[66];
|
|
uint8_t c[66];
|
|
int i;
|
|
int j;
|
|
|
|
printf("Performing packing/unpacking tests (not part of the ETSI conformance tests).\n");
|
|
/* Try trans-packing a lot of random data looking for before/after mismatch. */
|
|
for (j = 0; j < 1000; j++)
|
|
{
|
|
for (i = 0; i < 65; i++)
|
|
a[i] = rand();
|
|
repack_gsm0610_wav49_to_voip(b, a);
|
|
repack_gsm0610_voip_to_wav49(c, b);
|
|
if (memcmp(a, c, 65))
|
|
{
|
|
printf("Test failed: data mismatch\n");
|
|
exit(2);
|
|
}
|
|
|
|
for (i = 0; i < 66; i++)
|
|
a[i] = rand();
|
|
/* Insert the magic code */
|
|
a[0] = (a[0] & 0xF) | 0xD0;
|
|
a[33] = (a[33] & 0xF) | 0xD0;
|
|
repack_gsm0610_voip_to_wav49(b, a);
|
|
repack_gsm0610_wav49_to_voip(c, b);
|
|
//for (i = 0; i < 66; i++)
|
|
// printf("%2d: 0x%02X 0x%02X\n", i, a[i], c[i]);
|
|
if (memcmp(a, c, 66))
|
|
{
|
|
printf("Test failed: data mismatch\n");
|
|
exit(2);
|
|
}
|
|
}
|
|
printf("Test passed\n");
|
|
return 0;
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
AFfilehandle inhandle;
|
|
AFfilehandle outhandle;
|
|
AFfilesetup filesetup;
|
|
int frames;
|
|
int outframes;
|
|
float x;
|
|
int16_t pre_amp[HIST_LEN];
|
|
int16_t post_amp[HIST_LEN];
|
|
uint8_t gsm0610_data[HIST_LEN];
|
|
gsm0610_state_t *gsm0610_enc_state;
|
|
gsm0610_state_t *gsm0610_dec_state;
|
|
int etsitests;
|
|
int packing;
|
|
int i;
|
|
|
|
etsitests = TRUE;
|
|
packing = GSM0610_PACKING_NONE;
|
|
for (i = 1; i < argc; i++)
|
|
{
|
|
if (strcmp(argv[i], "-l") == 0)
|
|
{
|
|
etsitests = FALSE;
|
|
continue;
|
|
}
|
|
if (strcmp(argv[i], "-p") == 0)
|
|
{
|
|
packing = atoi(argv[++i]);
|
|
continue;
|
|
}
|
|
fprintf(stderr, "Unknown parameter %s specified.\n", argv[i]);
|
|
exit(2);
|
|
}
|
|
|
|
if (etsitests)
|
|
{
|
|
perform_linear_test(TRUE, 1, "Seq01");
|
|
perform_linear_test(TRUE, 1, "Seq02");
|
|
perform_linear_test(TRUE, 1, "Seq03");
|
|
perform_linear_test(TRUE, 1, "Seq04");
|
|
perform_linear_test(FALSE, 1, "Seq05");
|
|
perform_law_test(TRUE, 'a', "Seq01");
|
|
perform_law_test(TRUE, 'a', "Seq02");
|
|
perform_law_test(TRUE, 'a', "Seq03");
|
|
perform_law_test(TRUE, 'a', "Seq04");
|
|
perform_law_test(FALSE, 'a', "Seq05");
|
|
perform_law_test(TRUE, 'u', "Seq01");
|
|
perform_law_test(TRUE, 'u', "Seq02");
|
|
perform_law_test(TRUE, 'u', "Seq03");
|
|
perform_law_test(TRUE, 'u', "Seq04");
|
|
perform_law_test(FALSE, 'u', "Seq05");
|
|
/* This is not actually an ETSI test */
|
|
perform_pack_unpack_test();
|
|
|
|
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);
|
|
}
|
|
|
|
if ((gsm0610_enc_state = gsm0610_init(NULL, packing)) == NULL)
|
|
{
|
|
fprintf(stderr, " Cannot create encoder\n");
|
|
exit(2);
|
|
}
|
|
|
|
if ((gsm0610_dec_state = gsm0610_init(NULL, packing)) == NULL)
|
|
{
|
|
fprintf(stderr, " Cannot create decoder\n");
|
|
exit(2);
|
|
}
|
|
|
|
while ((frames = afReadFrames(inhandle, AF_DEFAULT_TRACK, pre_amp, 2*BLOCK_LEN)))
|
|
{
|
|
gsm0610_encode(gsm0610_enc_state, gsm0610_data, pre_amp, (packing == GSM0610_PACKING_WAV49) ? 1 : 2);
|
|
gsm0610_decode(gsm0610_dec_state, post_amp, gsm0610_data, (packing == GSM0610_PACKING_WAV49) ? 1 : 2);
|
|
outframes = afWriteFrames(outhandle, AF_DEFAULT_TRACK, post_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);
|
|
gsm0610_release(gsm0610_enc_state);
|
|
gsm0610_release(gsm0610_dec_state);
|
|
}
|
|
return 0;
|
|
}
|
|
/*- End of function --------------------------------------------------------*/
|
|
/*- End of file ------------------------------------------------------------*/
|