261 lines
6.6 KiB
C++
261 lines
6.6 KiB
C++
/*
|
|
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
/******************************************************************
|
|
Stand Alone test application for ISACFIX and ISAC LC
|
|
|
|
******************************************************************/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "typedefs.h"
|
|
|
|
#include "isacfix.h"
|
|
ISACFIX_MainStruct *ISACfix_inst;
|
|
|
|
#define FS 16000
|
|
|
|
|
|
typedef struct {
|
|
WebRtc_UWord32 arrival_time; /* samples */
|
|
WebRtc_UWord32 sample_count; /* samples */
|
|
WebRtc_UWord16 rtp_number;
|
|
} BottleNeckModel;
|
|
|
|
void get_arrival_time(int current_framesamples, /* samples */
|
|
int packet_size, /* bytes */
|
|
int bottleneck, /* excluding headers; bits/s */
|
|
BottleNeckModel *BN_data)
|
|
{
|
|
const int HeaderSize = 35;
|
|
int HeaderRate;
|
|
|
|
HeaderRate = HeaderSize * 8 * FS / current_framesamples; /* bits/s */
|
|
|
|
/* everything in samples */
|
|
BN_data->sample_count = BN_data->sample_count + current_framesamples;
|
|
|
|
BN_data->arrival_time += ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate);
|
|
|
|
if (BN_data->arrival_time < BN_data->sample_count)
|
|
BN_data->arrival_time = BN_data->sample_count;
|
|
|
|
BN_data->rtp_number++;
|
|
}
|
|
|
|
/*
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
*/
|
|
int main(int argc, char* argv[]){
|
|
|
|
/* Parameters */
|
|
FILE *pInFile, *pOutFile, *pChcFile;
|
|
WebRtc_Word8 inFile[40];
|
|
WebRtc_Word8 outFile[40];
|
|
WebRtc_Word8 chcFile[40];
|
|
WebRtc_Word8 codec[10];
|
|
WebRtc_Word16 bitrt, spType, size;
|
|
WebRtc_UWord16 frameLen;
|
|
WebRtc_Word16 sigOut[1000], sigIn[1000];
|
|
WebRtc_UWord16 bitStream[500]; /* double to 32 kbps for 60 ms */
|
|
|
|
WebRtc_Word16 chc, ok;
|
|
int noOfCalls, cdlen;
|
|
WebRtc_Word16 noOfLostFrames;
|
|
int err, errtype;
|
|
|
|
BottleNeckModel BN_data;
|
|
|
|
int totalbits =0;
|
|
int totalsmpls =0;
|
|
|
|
/*End Parameters*/
|
|
|
|
|
|
if ((argc==6)||(argc==7) ){
|
|
|
|
strcpy(codec,argv[5]);
|
|
|
|
if(argc==7){
|
|
if (!_stricmp("isac",codec)){
|
|
bitrt = atoi(argv[6]);
|
|
if ( (bitrt<10000)&&(bitrt>32000)){
|
|
printf("Error: Supported bit rate in the range 10000-32000 bps!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
}else{
|
|
printf("Error: Codec not recognized. Check spelling!\n");
|
|
exit(-1);
|
|
}
|
|
|
|
} else {
|
|
printf("Error: Codec not recognized. Check spelling!\n");
|
|
exit(-1);
|
|
}
|
|
} else {
|
|
printf("Error: Wrong number of input parameter!\n\n");
|
|
exit(-1);
|
|
}
|
|
|
|
frameLen = atoi(argv[4]);
|
|
strcpy(chcFile,argv[3]);
|
|
strcpy(outFile,argv[2]);
|
|
strcpy(inFile,argv[1]);
|
|
|
|
/* Open file streams */
|
|
if( (pInFile = fopen(inFile,"rb")) == NULL ) {
|
|
printf( "Error: Did not find input file!\n" );
|
|
exit(-1);
|
|
}
|
|
strcat(outFile,"_");
|
|
strcat(outFile, argv[4]);
|
|
strcat(outFile,"_");
|
|
strcat(outFile, codec);
|
|
|
|
if (argc==7){
|
|
strcat(outFile,"_");
|
|
strcat(outFile, argv[6]);
|
|
}
|
|
if (_stricmp("none", chcFile)){
|
|
strcat(outFile,"_");
|
|
strcat(outFile, "plc");
|
|
}
|
|
|
|
strcat(outFile, ".otp");
|
|
|
|
if (_stricmp("none", chcFile)){
|
|
if( (pChcFile = fopen(chcFile,"rb")) == NULL ) {
|
|
printf( "Error: Did not find channel file!\n" );
|
|
exit(-1);
|
|
}
|
|
}
|
|
/******************************************************************/
|
|
if (!_stricmp("isac", codec)){ /* ISAC */
|
|
if ((frameLen!=480)&&(frameLen!=960)) {
|
|
printf("Error: ISAC only supports 480 and 960 samples per frame (not %d)\n", frameLen);
|
|
exit(-1);
|
|
}
|
|
if( (pOutFile = fopen(outFile,"wb")) == NULL ) {
|
|
printf( "Could not open output file!\n" );
|
|
exit(-1);
|
|
}
|
|
ok=WebRtcIsacfix_Create(&ISACfix_inst);
|
|
if (ok!=0) {
|
|
printf("Couldn't allocate memory for iSAC fix instance\n");
|
|
exit(-1);
|
|
}
|
|
|
|
BN_data.arrival_time = 0;
|
|
BN_data.sample_count = 0;
|
|
BN_data.rtp_number = 0;
|
|
|
|
WebRtcIsacfix_EncoderInit(ISACfix_inst,1);
|
|
WebRtcIsacfix_DecoderInit(ISACfix_inst);
|
|
err = WebRtcIsacfix_Control(ISACfix_inst, bitrt, (frameLen>>4));
|
|
if (err < 0) {
|
|
/* exit if returned with error */
|
|
errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
|
|
printf("\n\n Error in initialization: %d.\n\n", errtype);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
/* loop over frame */
|
|
while (fread(sigIn,sizeof(WebRtc_Word16),frameLen,pInFile) == frameLen) {
|
|
|
|
noOfCalls=0;
|
|
cdlen=0;
|
|
while (cdlen<=0) {
|
|
cdlen=WebRtcIsacfix_Encode(ISACfix_inst,&sigIn[noOfCalls*160],(WebRtc_Word16*)bitStream);
|
|
if(cdlen==-1){
|
|
errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
|
|
printf("\n\nError in encoder: %d.\n\n", errtype);
|
|
exit(-1);
|
|
}
|
|
noOfCalls++;
|
|
}
|
|
|
|
|
|
if(_stricmp("none", chcFile)){
|
|
if (fread(&chc,sizeof(WebRtc_Word16),1,pChcFile)!=1) /* packet may be lost */
|
|
break;
|
|
} else {
|
|
chc = 1; /* packets never lost */
|
|
}
|
|
|
|
/* simulate packet handling through NetEq and the modem */
|
|
get_arrival_time(frameLen, cdlen, bitrt, &BN_data);
|
|
|
|
if (chc){ /* decode */
|
|
|
|
err = WebRtcIsacfix_UpdateBwEstimate1(ISACfix_inst,
|
|
bitStream,
|
|
cdlen,
|
|
BN_data.rtp_number,
|
|
BN_data.arrival_time);
|
|
|
|
if (err < 0) {
|
|
/* exit if returned with error */
|
|
errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
|
|
printf("\n\nError in decoder: %d.\n\n", errtype);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
size = WebRtcIsacfix_Decode(ISACfix_inst, bitStream, cdlen, sigOut, &spType);
|
|
if(size<=0){
|
|
/* exit if returned with error */
|
|
errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
|
|
printf("\n\nError in decoder: %d.\n\n", errtype);
|
|
exit(-1);
|
|
}
|
|
} else { /* PLC */
|
|
if (frameLen == 480){
|
|
noOfLostFrames = 1;
|
|
} else{
|
|
noOfLostFrames = 2;
|
|
}
|
|
size = WebRtcIsacfix_DecodePlc(ISACfix_inst, sigOut, noOfLostFrames );
|
|
if(size<=0){
|
|
errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
|
|
printf("\n\nError in decoder: %d.\n\n", errtype);
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
/* Write decoded speech to file */
|
|
fwrite(sigOut,sizeof(short),size,pOutFile);
|
|
|
|
totalbits += 8 * cdlen;
|
|
totalsmpls += size;
|
|
|
|
}
|
|
/******************************************************************/
|
|
}
|
|
|
|
// printf("\n\ntotal bits = %d bits", totalbits);
|
|
printf("\nmeasured average bitrate = %0.3f kbits/s", (double)totalbits * 16 / totalsmpls);
|
|
printf("\n");
|
|
|
|
|
|
fclose(pInFile);
|
|
fclose(pOutFile);
|
|
if (_stricmp("none", chcFile)){
|
|
fclose(pChcFile);
|
|
}
|
|
|
|
if (!_stricmp("isac", codec)){
|
|
WebRtcIsacfix_Free(ISACfix_inst);
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|