freeswitch/libs/ilbc/tests/ilbc_tests.c

352 lines
11 KiB
C

/*
* iLBC - a library for the iLBC codec
*
* ilbc_tests.c - Test the iLBC low bit rate speech codec.
*
* Adapted by Steve Underwood <steveu@coppice.org> from the reference
* iLBC code supplied in RFC3951.
*
* Copyright (C) The Internet Society (2004).
* All Rights Reserved.
*
* 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: ilbc_tests.c,v 1.1.1.1 2008/02/15 12:15:55 steveu Exp $
*/
/*! \file */
/*! \page ilbc_tests_page iLBC codec tests
\section ilbc_tests_page_sec_1 What does it do?
\section ilbc_tests_page_sec_2 How is it used?
To perform a general audio quality test, ilbc_tests should be run. The file ../localtests/short_nb_voice.wav
will be compressed to iLBC data, decompressed, and the resulting audio stored in post_ilbc.wav.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <inttypes.h>
#include <time.h>
#include <audiofile.h>
#include "ilbc.h"
#define IN_FILE_NAME "../localtests/dam9.wav"
#define REF_FILE_NAME "../localtests/dam9_lpc55.wav"
#define COMPRESS_FILE_NAME "lpc10_out.lpc10"
#define DECOMPRESS_FILE_NAME "lpc10_in.lpc10"
#define OUT_FILE_NAME "post_lpc10.wav"
#define SAMPLE_RATE 8000
/*---------------------------------------------------------------*
* Main program to test iLBC encoding and decoding
*
* Usage:
* exefile_name.exe <infile> <bytefile> <outfile> <channel>
*
* <infile> : Input file, speech for encoder (16-bit PCM file)
* <bytefile> : Bit stream output from the encoder
* <outfile> : Output file, decoded speech (16-bit PCM file)
* <channel> : Bit error file, optional (16-bit)
* 1 - Packet received correctly
* 0 - Packet Lost
*--------------------------------------------------------------*/
int main(int argc, char *argv[])
{
AFfilehandle inhandle;
AFfilehandle refhandle;
AFfilehandle outhandle;
AFfilesetup filesetup;
int frames;
int outframes;
int compress_file;
int decompress_file;
float x;
float starttime;
float runtime;
float outtime;
FILE *ifileid;
FILE *efileid;
FILE *ofileid;
FILE *cfileid;
int16_t data[ILBC_BLOCK_LEN_MAX];
uint8_t encoded_data[ILBC_NO_OF_BYTES_MAX];
int16_t decoded_data[ILBC_BLOCK_LEN_MAX];
int len;
int16_t pli;
int16_t mode;
int blockcount = 0;
int packetlosscount = 0;
/* Create structs */
ilbc_encode_state_t Enc_Inst;
ilbc_decode_state_t Dec_Inst;
compress_file = -1;
decompress_file = -1;
inhandle = AF_NULL_FILEHANDLE;
refhandle = AF_NULL_FILEHANDLE;
outhandle = AF_NULL_FILEHANDLE;
#if 0
if (!decompress)
{
if ((inhandle = afOpenFile(in_file_name, "r", 0)) == AF_NULL_FILEHANDLE)
{
fprintf(stderr, " Cannot open wave file '%s'\n", in_file_name);
exit(2);
}
if ((x = afGetFrameSize(inhandle, AF_DEFAULT_TRACK, 1)) != 2.0)
{
fprintf(stderr, " Unexpected frame size in wave file '%s'\n", in_file_name);
exit(2);
}
if ((x = afGetRate(inhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE)
{
fprintf(stderr, " Unexpected sample rate in wave file '%s'\n", in_file_name);
exit(2);
}
if ((x = afGetChannels(inhandle, AF_DEFAULT_TRACK)) != 1.0)
{
fprintf(stderr, " 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);
}
if ((refhandle = afOpenFile(REF_FILE_NAME, "r", 0)) == AF_NULL_FILEHANDLE)
{
fprintf(stderr, " Cannot open wave file '%s'\n", REF_FILE_NAME);
exit(2);
}
if ((x = afGetFrameSize(refhandle, AF_DEFAULT_TRACK, 1)) != 2.0)
{
fprintf(stderr, " Unexpected frame size in wave file '%s'\n", REF_FILE_NAME);
exit(2);
}
if ((x = afGetRate(refhandle, AF_DEFAULT_TRACK)) != (float) SAMPLE_RATE)
{
fprintf(stderr, " Unexpected sample rate in wave file '%s'\n", REF_FILE_NAME);
exit(2);
}
if ((x = afGetChannels(refhandle, AF_DEFAULT_TRACK)) != 1.0)
{
fprintf(stderr, " Unexpected number of channels in wave file '%s'\n", REF_FILE_NAME);
exit(2);
}
}
else
{
if ((decompress_file = open(DECOMPRESS_FILE_NAME, O_RDONLY)) < 0)
{
fprintf(stderr, " Cannot open decompressed data file '%s'\n", DECOMPRESS_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);
if ((outhandle = afOpenFile(OUT_FILE_NAME, "w", filesetup)) == AF_NULL_FILEHANDLE)
{
fprintf(stderr, " Cannot create wave file '%s'\n", OUT_FILE_NAME);
exit(2);
}
#endif
if ((argc != 5) && (argc != 6))
{
fprintf(stderr,
"\n*-----------------------------------------------*\n");
fprintf(stderr,
" %s <20,30> input encoded decoded (channel)\n\n",
argv[0]);
fprintf(stderr,
" mode : Frame size for the encoding/decoding\n");
fprintf(stderr,
" 20 - 20 ms\n");
fprintf(stderr,
" 30 - 30 ms\n");
fprintf(stderr,
" input : Speech for encoder (16-bit pcm file)\n");
fprintf(stderr,
" encoded : Encoded bit stream\n");
fprintf(stderr,
" decoded : Decoded speech (16-bit pcm file)\n");
fprintf(stderr,
" channel : Packet loss pattern, optional (16-bit)\n");
fprintf(stderr,
" 1 - Packet received correctly\n");
fprintf(stderr,
" 0 - Packet Lost\n");
fprintf(stderr,
"*-----------------------------------------------*\n\n");
exit(1);
}
mode = atoi(argv[1]);
if (mode != 20 && mode != 30)
{
fprintf(stderr,"Wrong mode %s, must be 20, or 30\n",
argv[1]);
exit(2);
}
if ((ifileid = fopen(argv[2],"rb")) == NULL)
{
fprintf(stderr,"Cannot open input file %s\n", argv[2]);
exit(2);
}
if ((efileid = fopen(argv[3],"wb")) == NULL)
{
fprintf(stderr, "Cannot open encoded file %s\n",
argv[3]);
exit(1);
}
if ((ofileid = fopen(argv[4],"wb")) == NULL)
{
fprintf(stderr, "Cannot open decoded file %s\n",
argv[4]);
exit(1);
}
if (argc == 6)
{
if( (cfileid=fopen(argv[5],"rb")) == NULL)
{
fprintf(stderr, "Cannot open channel file %s\n",
argv[5]);
exit(1);
}
}
else
{
cfileid=NULL;
}
/* print info */
fprintf(stderr, "\n");
fprintf(stderr,
"*---------------------------------------------------*\n");
fprintf(stderr,
"* *\n");
fprintf(stderr,
"* iLBC test program *\n");
fprintf(stderr,
"* *\n");
fprintf(stderr,
"* *\n");
fprintf(stderr,
"*---------------------------------------------------*\n");
fprintf(stderr, "\nMode : %2d ms\n", mode);
fprintf(stderr, "Input file : %s\n", argv[2]);
fprintf(stderr, "Encoded file : %s\n", argv[3]);
fprintf(stderr, "Output file : %s\n", argv[4]);
if (argc == 6)
fprintf(stderr,"Channel file : %s\n", argv[5]);
fprintf(stderr, "\n");
/* Initialization */
ilbc_encode_init(&Enc_Inst, mode);
ilbc_decode_init(&Dec_Inst, mode, 1);
/* Runtime statistics */
starttime = clock()/(float)CLOCKS_PER_SEC;
/* Loop over input blocks */
while (fread(data, sizeof(int16_t), Enc_Inst.blockl, ifileid) == Enc_Inst.blockl)
{
blockcount++;
/* Encoding */
fprintf(stderr, "--- Encoding block %i --- ",blockcount);
len = ilbc_encode(&Enc_Inst, encoded_data, data, Enc_Inst.blockl);
fprintf(stderr, "\r");
/* Write byte file */
fwrite(encoded_data, sizeof(uint8_t), len, efileid);
/* Get channel data if provided */
if (argc == 6)
{
if (fread(&pli, sizeof(int16_t), 1, cfileid))
{
if ((pli != 0) && (pli != 1))
{
fprintf(stderr, "Error in channel file\n");
exit(0);
}
if (pli == 0)
{
/* Packet loss -> remove info from frame */
memset(encoded_data, 0, len);
packetlosscount++;
}
}
else
{
fprintf(stderr, "Error. Channel file too int16_t\n");
exit(0);
}
}
else
{
pli = 1;
}
/* Decoding */
fprintf(stderr, "--- Decoding block %i --- ", blockcount);
if (pli)
len = ilbc_decode(&Dec_Inst, decoded_data, encoded_data, len);
else
len = ilbc_fillin(&Dec_Inst, decoded_data, len);
fprintf(stderr, "\r");
/* Write output file */
fwrite(decoded_data, sizeof(int16_t), len, ofileid);
}
/* Runtime statistics */
runtime = (float) (clock()/(float) CLOCKS_PER_SEC - starttime);
outtime = (float) ((float) blockcount*(float) mode/1000.0f);
printf("\n\nLength of speech file: %.1f s\n", outtime);
printf("Packet loss : %.1f%%\n",
100.0f*(float) packetlosscount/(float) blockcount);
printf("Time to run iLBC :");
printf(" %.1f s (%.1f%% of realtime)\n\n", runtime, 100.0f*runtime/outtime);
/* close files */
fclose(ifileid);
fclose(efileid);
fclose(ofileid);
if (argc == 6)
fclose(cfileid);
return(0);
}