Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 /******************************************************************
     12 
     13 	iLBC Speech Coder ANSI-C Source Code
     14 
     15         iLBC_test.c
     16 
     17 ******************************************************************/
     18 
     19 #include <math.h>
     20 #include <stdlib.h>
     21 #include <stdio.h>
     22 #include <string.h>
     23 
     24 #include "webrtc/modules/audio_coding/codecs/ilbc/defines.h"
     25 #include "webrtc/modules/audio_coding/codecs/ilbc/nit_encode.h"
     26 #include "webrtc/modules/audio_coding/codecs/ilbc/encode.h"
     27 #include "webrtc/modules/audio_coding/codecs/ilbc/init_decode.h"
     28 #include "webrtc/modules/audio_coding/codecs/ilbc/decode.h"
     29 #include "webrtc/modules/audio_coding/codecs/ilbc/constants.h"
     30 #include "webrtc/modules/audio_coding/codecs/ilbc/ilbc.h"
     31 
     32 #define ILBCNOOFWORDS_MAX (NO_OF_BYTES_30MS)/2
     33 
     34 /* Runtime statistics */
     35 #include <time.h>
     36 /* #define CLOCKS_PER_SEC  1000 */
     37 
     38 /*----------------------------------------------------------------*
     39  *  Encoder interface function
     40  *---------------------------------------------------------------*/
     41 
     42 short encode(                         /* (o) Number of bytes encoded */
     43     IlbcEncoder *iLBCenc_inst,    /* (i/o) Encoder instance */
     44     int16_t *encoded_data,      /* (o) The encoded bytes */
     45     int16_t *data               /* (i) The signal block to encode */
     46                                                         ){
     47 
     48   /* do the actual encoding */
     49   WebRtcIlbcfix_Encode((uint16_t *)encoded_data, data, iLBCenc_inst);
     50 
     51   return (iLBCenc_inst->no_of_bytes);
     52 }
     53 
     54 /*----------------------------------------------------------------*
     55  *  Decoder interface function
     56  *---------------------------------------------------------------*/
     57 
     58 short decode( /* (o) Number of decoded samples */
     59     IlbcDecoder *iLBCdec_inst, /* (i/o) Decoder instance */
     60     short *decoded_data, /* (o) Decoded signal block */
     61     short *encoded_data, /* (i) Encoded bytes */
     62     short mode           /* (i) 0=PL, 1=Normal */
     63               ){
     64 
     65   /* check if mode is valid */
     66 
     67   if (mode<0 || mode>1) {
     68     printf("\nERROR - Wrong mode - 0, 1 allowed\n"); exit(3);}
     69 
     70   /* do actual decoding of block */
     71 
     72   WebRtcIlbcfix_Decode(decoded_data, (uint16_t *)encoded_data,
     73                        iLBCdec_inst, mode);
     74 
     75   return (iLBCdec_inst->blockl);
     76 }
     77 
     78 /*----------------------------------------------------------------*
     79  *  Main program to test iLBC encoding and decoding
     80  *
     81  *  Usage:
     82  *		exefile_name.exe <infile> <bytefile> <outfile> <channelfile>
     83  *
     84  *---------------------------------------------------------------*/
     85 
     86 #define MAXFRAMES   10000
     87 #define MAXFILELEN (BLOCKL_MAX*MAXFRAMES)
     88 
     89 int main(int argc, char* argv[])
     90 {
     91 
     92   /* Runtime statistics */
     93 
     94   float starttime1, starttime2;
     95   float runtime1, runtime2;
     96   float outtime;
     97 
     98   FILE *ifileid,*efileid,*ofileid, *chfileid;
     99   short *inputdata, *encodeddata, *decodeddata;
    100   short *channeldata;
    101   int blockcount = 0, noOfBlocks=0, i, noOfLostBlocks=0;
    102   short mode;
    103   IlbcEncoder Enc_Inst;
    104   IlbcDecoder Dec_Inst;
    105 
    106   short frameLen;
    107   short count;
    108 #ifdef SPLIT_10MS
    109   short size;
    110 #endif
    111 
    112   inputdata=(short*) malloc(MAXFILELEN*sizeof(short));
    113   if (inputdata==NULL) {
    114     fprintf(stderr,"Could not allocate memory for vector\n");
    115     exit(0);
    116   }
    117   encodeddata=(short*) malloc(ILBCNOOFWORDS_MAX*MAXFRAMES*sizeof(short));
    118   if (encodeddata==NULL) {
    119     fprintf(stderr,"Could not allocate memory for vector\n");
    120     free(inputdata);
    121     exit(0);
    122   }
    123   decodeddata=(short*) malloc(MAXFILELEN*sizeof(short));
    124   if (decodeddata==NULL) {
    125     fprintf(stderr,"Could not allocate memory for vector\n");
    126     free(inputdata);
    127     free(encodeddata);
    128     exit(0);
    129   }
    130   channeldata=(short*) malloc(MAXFRAMES*sizeof(short));
    131   if (channeldata==NULL) {
    132     fprintf(stderr,"Could not allocate memory for vector\n");
    133     free(inputdata);
    134     free(encodeddata);
    135     free(decodeddata);
    136     exit(0);
    137   }
    138 
    139   /* get arguments and open files */
    140 
    141   if (argc != 6 ) {
    142     fprintf(stderr, "%s mode inputfile bytefile outputfile channelfile\n",
    143             argv[0]);
    144     fprintf(stderr, "Example:\n");
    145     fprintf(stderr, "%s <30,20> in.pcm byte.dat out.pcm T30.0.dat\n", argv[0]);
    146     exit(1);
    147   }
    148   mode=atoi(argv[1]);
    149   if (mode != 20 && mode != 30) {
    150     fprintf(stderr,"Wrong mode %s, must be 20, or 30\n", argv[1]);
    151     exit(2);
    152   }
    153   if ( (ifileid=fopen(argv[2],"rb")) == NULL) {
    154     fprintf(stderr,"Cannot open input file %s\n", argv[2]);
    155     exit(2);}
    156   if ( (efileid=fopen(argv[3],"wb")) == NULL) {
    157     fprintf(stderr, "Cannot open channelfile file %s\n",
    158             argv[3]); exit(3);}
    159   if( (ofileid=fopen(argv[4],"wb")) == NULL) {
    160     fprintf(stderr, "Cannot open output file %s\n",
    161             argv[4]); exit(3);}
    162   if ( (chfileid=fopen(argv[5],"rb")) == NULL) {
    163     fprintf(stderr,"Cannot open channel file file %s\n", argv[5]);
    164     exit(2);}
    165 
    166 
    167   /* print info */
    168 #ifndef PRINT_MIPS
    169   fprintf(stderr, "\n");
    170   fprintf(stderr,
    171           "*---------------------------------------------------*\n");
    172   fprintf(stderr,
    173           "*                                                   *\n");
    174   fprintf(stderr,
    175           "*      iLBCtest                                     *\n");
    176   fprintf(stderr,
    177           "*                                                   *\n");
    178   fprintf(stderr,
    179           "*                                                   *\n");
    180   fprintf(stderr,
    181           "*---------------------------------------------------*\n");
    182 #ifdef SPLIT_10MS
    183   fprintf(stderr,"\n10ms split with raw mode: %2d ms\n", mode);
    184 #else
    185   fprintf(stderr,"\nMode          : %2d ms\n", mode);
    186 #endif
    187   fprintf(stderr,"\nInput file    : %s\n", argv[2]);
    188   fprintf(stderr,"Coded file    : %s\n", argv[3]);
    189   fprintf(stderr,"Output file   : %s\n\n", argv[4]);
    190   fprintf(stderr,"Channel file  : %s\n\n", argv[5]);
    191 #endif
    192 
    193   /* Initialization */
    194 
    195   WebRtcIlbcfix_EncoderInit(&Enc_Inst, mode);
    196   WebRtcIlbcfix_DecoderInit(&Dec_Inst, mode, 1);
    197 
    198   /* extract the input file and channel file */
    199 
    200 #ifdef SPLIT_10MS
    201   frameLen = (mode==20)? 80:160;
    202   fread(Enc_Inst.past_samples, sizeof(short), frameLen, ifileid);
    203   Enc_Inst.section = 0;
    204 
    205   while( fread(&inputdata[noOfBlocks*80], sizeof(short),
    206                80, ifileid) == 80 ) {
    207     noOfBlocks++;
    208   }
    209 
    210   noOfBlocks += frameLen/80;
    211   frameLen = 80;
    212 #else
    213   frameLen = Enc_Inst.blockl;
    214 
    215   while( fread(&inputdata[noOfBlocks*Enc_Inst.blockl],sizeof(short),
    216                Enc_Inst.blockl,ifileid)==(uint16_t)Enc_Inst.blockl){
    217     noOfBlocks++;
    218   }
    219 #endif
    220 
    221 
    222   while ((fread(&channeldata[blockcount],sizeof(short), 1,chfileid)==1)
    223             && ( blockcount < noOfBlocks/(Enc_Inst.blockl/frameLen) )) {
    224     blockcount++;
    225   }
    226 
    227   if ( blockcount < noOfBlocks/(Enc_Inst.blockl/frameLen) ) {
    228     fprintf(stderr,"Channel file %s is too short\n", argv[4]);
    229     free(inputdata);
    230     free(encodeddata);
    231     free(decodeddata);
    232     free(channeldata);
    233     exit(0);
    234   }
    235 
    236   count=0;
    237 
    238   /* Runtime statistics */
    239 
    240   starttime1 = clock()/(float)CLOCKS_PER_SEC;
    241 
    242   /* Encoding loop */
    243 #ifdef PRINT_MIPS
    244   printf("-1 -1\n");
    245 #endif
    246 
    247 #ifdef SPLIT_10MS
    248   /* "Enc_Inst.section != 0" is to make sure we run through full
    249      lengths of all vectors for 10ms split mode.
    250   */
    251   //   while( (count < noOfBlocks) || (Enc_Inst.section != 0) )    {
    252   while( count < blockcount * (Enc_Inst.blockl/frameLen) )    {
    253 
    254     encode(&Enc_Inst, &encodeddata[Enc_Inst.no_of_words *
    255                                    (count/(Enc_Inst.nsub/2))],
    256            &inputdata[frameLen * count] );
    257 #else
    258     while (count < noOfBlocks) {
    259       encode( &Enc_Inst, &encodeddata[Enc_Inst.no_of_words * count],
    260               &inputdata[frameLen * count] );
    261 #endif
    262 
    263 #ifdef PRINT_MIPS
    264       printf("-1 -1\n");
    265 #endif
    266 
    267       count++;
    268     }
    269 
    270     count=0;
    271 
    272     /* Runtime statistics */
    273 
    274     starttime2=clock()/(float)CLOCKS_PER_SEC;
    275     runtime1 = (float)(starttime2-starttime1);
    276 
    277     /* Decoding loop */
    278 
    279     while (count < blockcount) {
    280       if (channeldata[count]==1) {
    281         /* Normal decoding */
    282         decode(&Dec_Inst, &decodeddata[count * Dec_Inst.blockl],
    283                &encodeddata[Dec_Inst.no_of_words * count], 1);
    284       } else if (channeldata[count]==0) {
    285         /* PLC */
    286         short emptydata[ILBCNOOFWORDS_MAX];
    287         memset(emptydata, 0, Dec_Inst.no_of_words*sizeof(short));
    288         decode(&Dec_Inst, &decodeddata[count*Dec_Inst.blockl],
    289                emptydata, 0);
    290         noOfLostBlocks++;
    291       } else {
    292         printf("Error in channel file (values have to be either 1 or 0)\n");
    293         exit(0);
    294       }
    295 #ifdef PRINT_MIPS
    296       printf("-1 -1\n");
    297 #endif
    298 
    299       count++;
    300     }
    301 
    302     /* Runtime statistics */
    303 
    304     runtime2 = (float)(clock()/(float)CLOCKS_PER_SEC-starttime2);
    305 
    306     outtime = (float)((float)blockcount*
    307                       (float)mode/1000.0);
    308 
    309 #ifndef PRINT_MIPS
    310     printf("\nLength of speech file: %.1f s\n", outtime);
    311     printf("Lost frames          : %.1f%%\n\n", 100*(float)noOfLostBlocks/(float)blockcount);
    312 
    313     printf("Time to run iLBC_encode+iLBC_decode:");
    314     printf(" %.1f s (%.1f%% of realtime)\n", runtime1+runtime2,
    315            (100*(runtime1+runtime2)/outtime));
    316 
    317     printf("Time in iLBC_encode                :");
    318     printf(" %.1f s (%.1f%% of total runtime)\n",
    319            runtime1, 100.0*runtime1/(runtime1+runtime2));
    320 
    321     printf("Time in iLBC_decode                :");
    322     printf(" %.1f s (%.1f%% of total runtime)\n\n",
    323            runtime2, 100.0*runtime2/(runtime1+runtime2));
    324 #endif
    325 
    326     /* Write data to files */
    327     for (i=0; i<blockcount; i++) {
    328       fwrite(&encodeddata[i*Enc_Inst.no_of_words], sizeof(short),
    329              Enc_Inst.no_of_words, efileid);
    330     }
    331     for (i=0;i<blockcount;i++) {
    332       fwrite(&decodeddata[i*Enc_Inst.blockl],sizeof(short),Enc_Inst.blockl,ofileid);
    333     }
    334 
    335     /* return memory and close files */
    336 
    337     free(inputdata);
    338     free(encodeddata);
    339     free(decodeddata);
    340     free(channeldata);
    341     fclose(ifileid);  fclose(efileid); fclose(ofileid);
    342     return(0);
    343   }
    344