/* * 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. */ /****************************************************************** iLBC Speech Coder ANSI-C Source Code iLBC_test.c ******************************************************************/ #include #include #include #include #include "modules/audio_coding/codecs/ilbc/defines.h" #include "modules/audio_coding/codecs/ilbc/nit_encode.h" #include "modules/audio_coding/codecs/ilbc/encode.h" #include "modules/audio_coding/codecs/ilbc/init_decode.h" #include "modules/audio_coding/codecs/ilbc/decode.h" #include "modules/audio_coding/codecs/ilbc/constants.h" #include "modules/audio_coding/codecs/ilbc/ilbc.h" #define ILBCNOOFWORDS_MAX (NO_OF_BYTES_30MS)/2 /* Runtime statistics */ #include /* #define CLOCKS_PER_SEC 1000 */ /*----------------------------------------------------------------* * Encoder interface function *---------------------------------------------------------------*/ short encode( /* (o) Number of bytes encoded */ IlbcEncoder *iLBCenc_inst, /* (i/o) Encoder instance */ int16_t *encoded_data, /* (o) The encoded bytes */ int16_t *data /* (i) The signal block to encode */ ){ /* do the actual encoding */ WebRtcIlbcfix_Encode((uint16_t *)encoded_data, data, iLBCenc_inst); return (iLBCenc_inst->no_of_bytes); } /*----------------------------------------------------------------* * Decoder interface function *---------------------------------------------------------------*/ short decode( /* (o) Number of decoded samples */ IlbcDecoder *iLBCdec_inst, /* (i/o) Decoder instance */ short *decoded_data, /* (o) Decoded signal block */ short *encoded_data, /* (i) Encoded bytes */ short mode /* (i) 0=PL, 1=Normal */ ){ /* check if mode is valid */ if (mode<0 || mode>1) { printf("\nERROR - Wrong mode - 0, 1 allowed\n"); exit(3);} /* do actual decoding of block */ WebRtcIlbcfix_Decode(decoded_data, (uint16_t *)encoded_data, iLBCdec_inst, mode); return (iLBCdec_inst->blockl); } /*----------------------------------------------------------------* * Main program to test iLBC encoding and decoding * * Usage: * exefile_name.exe * *---------------------------------------------------------------*/ #define MAXFRAMES 10000 #define MAXFILELEN (BLOCKL_MAX*MAXFRAMES) int main(int argc, char* argv[]) { /* Runtime statistics */ float starttime1, starttime2; float runtime1, runtime2; float outtime; FILE *ifileid,*efileid,*ofileid, *chfileid; short *inputdata, *encodeddata, *decodeddata; short *channeldata; int blockcount = 0, noOfBlocks=0, i, noOfLostBlocks=0; short mode; IlbcEncoder Enc_Inst; IlbcDecoder Dec_Inst; short frameLen; short count; #ifdef SPLIT_10MS short size; #endif inputdata=(short*) malloc(MAXFILELEN*sizeof(short)); if (inputdata==NULL) { fprintf(stderr,"Could not allocate memory for vector\n"); exit(0); } encodeddata=(short*) malloc(ILBCNOOFWORDS_MAX*MAXFRAMES*sizeof(short)); if (encodeddata==NULL) { fprintf(stderr,"Could not allocate memory for vector\n"); free(inputdata); exit(0); } decodeddata=(short*) malloc(MAXFILELEN*sizeof(short)); if (decodeddata==NULL) { fprintf(stderr,"Could not allocate memory for vector\n"); free(inputdata); free(encodeddata); exit(0); } channeldata=(short*) malloc(MAXFRAMES*sizeof(short)); if (channeldata==NULL) { fprintf(stderr,"Could not allocate memory for vector\n"); free(inputdata); free(encodeddata); free(decodeddata); exit(0); } /* get arguments and open files */ if (argc != 6 ) { fprintf(stderr, "%s mode inputfile bytefile outputfile channelfile\n", argv[0]); fprintf(stderr, "Example:\n"); fprintf(stderr, "%s <30,20> in.pcm byte.dat out.pcm T30.0.dat\n", argv[0]); 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 channelfile file %s\n", argv[3]); exit(3);} if( (ofileid=fopen(argv[4],"wb")) == NULL) { fprintf(stderr, "Cannot open output file %s\n", argv[4]); exit(3);} if ( (chfileid=fopen(argv[5],"rb")) == NULL) { fprintf(stderr,"Cannot open channel file file %s\n", argv[5]); exit(2);} /* print info */ #ifndef PRINT_MIPS fprintf(stderr, "\n"); fprintf(stderr, "*---------------------------------------------------*\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "* iLBCtest *\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "* *\n"); fprintf(stderr, "*---------------------------------------------------*\n"); #ifdef SPLIT_10MS fprintf(stderr,"\n10ms split with raw mode: %2d ms\n", mode); #else fprintf(stderr,"\nMode : %2d ms\n", mode); #endif fprintf(stderr,"\nInput file : %s\n", argv[2]); fprintf(stderr,"Coded file : %s\n", argv[3]); fprintf(stderr,"Output file : %s\n\n", argv[4]); fprintf(stderr,"Channel file : %s\n\n", argv[5]); #endif /* Initialization */ WebRtcIlbcfix_EncoderInit(&Enc_Inst, mode); WebRtcIlbcfix_DecoderInit(&Dec_Inst, mode, 1); /* extract the input file and channel file */ #ifdef SPLIT_10MS frameLen = (mode==20)? 80:160; fread(Enc_Inst.past_samples, sizeof(short), frameLen, ifileid); Enc_Inst.section = 0; while( fread(&inputdata[noOfBlocks*80], sizeof(short), 80, ifileid) == 80 ) { noOfBlocks++; } noOfBlocks += frameLen/80; frameLen = 80; #else frameLen = Enc_Inst.blockl; while( fread(&inputdata[noOfBlocks*Enc_Inst.blockl],sizeof(short), Enc_Inst.blockl,ifileid)==(uint16_t)Enc_Inst.blockl){ noOfBlocks++; } #endif while ((fread(&channeldata[blockcount],sizeof(short), 1,chfileid)==1) && ( blockcount < noOfBlocks/(Enc_Inst.blockl/frameLen) )) { blockcount++; } if ( blockcount < noOfBlocks/(Enc_Inst.blockl/frameLen) ) { fprintf(stderr,"Channel file %s is too short\n", argv[4]); free(inputdata); free(encodeddata); free(decodeddata); free(channeldata); exit(0); } count=0; /* Runtime statistics */ starttime1 = clock()/(float)CLOCKS_PER_SEC; /* Encoding loop */ #ifdef PRINT_MIPS printf("-1 -1\n"); #endif #ifdef SPLIT_10MS /* "Enc_Inst.section != 0" is to make sure we run through full lengths of all vectors for 10ms split mode. */ // while( (count < noOfBlocks) || (Enc_Inst.section != 0) ) { while( count < blockcount * (Enc_Inst.blockl/frameLen) ) { encode(&Enc_Inst, &encodeddata[Enc_Inst.no_of_words * (count/(Enc_Inst.nsub/2))], &inputdata[frameLen * count] ); #else while (count < noOfBlocks) { encode( &Enc_Inst, &encodeddata[Enc_Inst.no_of_words * count], &inputdata[frameLen * count] ); #endif #ifdef PRINT_MIPS printf("-1 -1\n"); #endif count++; } count=0; /* Runtime statistics */ starttime2=clock()/(float)CLOCKS_PER_SEC; runtime1 = (float)(starttime2-starttime1); /* Decoding loop */ while (count < blockcount) { if (channeldata[count]==1) { /* Normal decoding */ decode(&Dec_Inst, &decodeddata[count * Dec_Inst.blockl], &encodeddata[Dec_Inst.no_of_words * count], 1); } else if (channeldata[count]==0) { /* PLC */ short emptydata[ILBCNOOFWORDS_MAX]; memset(emptydata, 0, Dec_Inst.no_of_words*sizeof(short)); decode(&Dec_Inst, &decodeddata[count*Dec_Inst.blockl], emptydata, 0); noOfLostBlocks++; } else { printf("Error in channel file (values have to be either 1 or 0)\n"); exit(0); } #ifdef PRINT_MIPS printf("-1 -1\n"); #endif count++; } /* Runtime statistics */ runtime2 = (float)(clock()/(float)CLOCKS_PER_SEC-starttime2); outtime = (float)((float)blockcount* (float)mode/1000.0); #ifndef PRINT_MIPS printf("\nLength of speech file: %.1f s\n", outtime); printf("Lost frames : %.1f%%\n\n", 100*(float)noOfLostBlocks/(float)blockcount); printf("Time to run iLBC_encode+iLBC_decode:"); printf(" %.1f s (%.1f%% of realtime)\n", runtime1+runtime2, (100*(runtime1+runtime2)/outtime)); printf("Time in iLBC_encode :"); printf(" %.1f s (%.1f%% of total runtime)\n", runtime1, 100.0*runtime1/(runtime1+runtime2)); printf("Time in iLBC_decode :"); printf(" %.1f s (%.1f%% of total runtime)\n\n", runtime2, 100.0*runtime2/(runtime1+runtime2)); #endif /* Write data to files */ for (i=0; i