| /* |
| * 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 <math.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #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 <time.h> |
| /* #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 <infile> <bytefile> <outfile> <channelfile> |
| * |
| *---------------------------------------------------------------*/ |
| |
| #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<blockcount; i++) { |
| fwrite(&encodeddata[i*Enc_Inst.no_of_words], sizeof(short), |
| Enc_Inst.no_of_words, efileid); |
| } |
| for (i=0;i<blockcount;i++) { |
| fwrite(&decodeddata[i*Enc_Inst.blockl],sizeof(short),Enc_Inst.blockl,ofileid); |
| } |
| |
| /* return memory and close files */ |
| |
| free(inputdata); |
| free(encodeddata); |
| free(decodeddata); |
| free(channeldata); |
| fclose(ifileid); fclose(efileid); fclose(ofileid); |
| return(0); |
| } |