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  * test_iSACfixfloat.c
     13  *
     14  * Test compatibility and quality between floating- and fixed-point code
     15  * */
     16 
     17 #include <stdio.h>
     18 #include <stdlib.h>
     19 #include <string.h>
     20 
     21 /* include API */
     22 #include "isac.h"
     23 #include "isacfix.h"
     24 #include "webrtc/base/format_macros.h"
     25 
     26 /* max number of samples per frame (= 60 ms frame) */
     27 #define MAX_FRAMESAMPLES 960
     28 /* number of samples per 10ms frame */
     29 #define FRAMESAMPLES_10ms 160
     30 /* sampling frequency (Hz) */
     31 #define FS 16000
     32 
     33 /* Runtime statistics */
     34 #include <time.h>
     35 #define CLOCKS_PER_SEC 1000
     36 
     37 // FILE *histfile, *ratefile;
     38 
     39 /* function for reading audio data from PCM file */
     40 int readframe(int16_t* data, FILE* inp, int length) {
     41   short k, rlen, status = 0;
     42 
     43   rlen = fread(data, sizeof(int16_t), length, inp);
     44   if (rlen < length) {
     45     for (k = rlen; k < length; k++)
     46       data[k] = 0;
     47     status = 1;
     48   }
     49 
     50   return status;
     51 }
     52 
     53 typedef struct {
     54   uint32_t send_time;    /* samples */
     55   uint32_t arrival_time; /* samples */
     56   uint32_t sample_count; /* samples */
     57   uint16_t rtp_number;
     58 } BottleNeckModel;
     59 
     60 void get_arrival_time(int current_framesamples, /* samples */
     61                       size_t packet_size,       /* bytes */
     62                       int bottleneck,           /* excluding headers; bits/s */
     63                       BottleNeckModel* BN_data) {
     64   const int HeaderSize = 35;
     65   int HeaderRate;
     66 
     67   HeaderRate = HeaderSize * 8 * FS / current_framesamples; /* bits/s */
     68 
     69   /* everything in samples */
     70   BN_data->sample_count = BN_data->sample_count + current_framesamples;
     71 
     72   BN_data->arrival_time += (uint32_t)
     73       (((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate));
     74   BN_data->send_time += current_framesamples;
     75 
     76   if (BN_data->arrival_time < BN_data->sample_count)
     77     BN_data->arrival_time = BN_data->sample_count;
     78 
     79   BN_data->rtp_number++;
     80 }
     81 
     82 int main(int argc, char* argv[]) {
     83   char inname[50], outname[50], bottleneck_file[50], bitfilename[60],
     84       bitending[10] = "_bits.pcm";
     85   FILE* inp, *outp, *f_bn, *bitsp;
     86   int framecnt, endfile;
     87 
     88   int i, j, errtype, plc = 0;
     89   int16_t CodingMode;
     90   int16_t bottleneck;
     91 
     92   int framesize = 30; /* ms */
     93   // int framesize = 60; /* To invoke cisco complexity case at frame 2252 */
     94 
     95   int cur_framesmpls, err;
     96 
     97   /* Runtime statistics */
     98   double starttime;
     99   double runtime;
    100   double length_file;
    101 
    102   size_t stream_len = 0;
    103   int declen;
    104 
    105   int16_t shortdata[FRAMESAMPLES_10ms];
    106   int16_t decoded[MAX_FRAMESAMPLES];
    107   uint16_t streamdata[600];
    108   int16_t speechType[1];
    109 
    110   // int16_t* iSACstruct;
    111 
    112   char version_number[20];
    113   int mode = -1, tmp, nbTest = 0; /*,sss;*/
    114 
    115 #if !defined(NDEBUG)
    116   FILE* fy;
    117   double kbps;
    118   size_t totalbits = 0;
    119   int totalsmpls = 0;
    120 #endif
    121 
    122   /* only one structure used for ISAC encoder */
    123   ISAC_MainStruct* ISAC_main_inst;
    124   ISACFIX_MainStruct* ISACFIX_main_inst;
    125 
    126   BottleNeckModel BN_data;
    127   f_bn = NULL;
    128 
    129 #if !defined(NDEBUG)
    130   fy = fopen("bit_rate.dat", "w");
    131   fclose(fy);
    132   fy = fopen("bytes_frames.dat", "w");
    133   fclose(fy);
    134 #endif
    135 
    136   // histfile = fopen("histo.dat", "ab");
    137   // ratefile = fopen("rates.dat", "ab");
    138 
    139   /* handling wrong input arguments in the command line */
    140   if ((argc < 6) || (argc > 10)) {
    141     printf("\n\nWrong number of arguments or flag values.\n\n");
    142 
    143     printf("\n");
    144     WebRtcIsacfix_version(version_number);
    145     printf("iSAC version %s \n\n", version_number);
    146 
    147     printf("Usage:\n\n");
    148     printf("./kenny.exe [-I] bottleneck_value infile outfile \n\n");
    149     printf("with:\n");
    150 
    151     printf("[-I]            : If -I option is specified, the coder will use\n");
    152     printf("                  an instantaneous Bottleneck value. If not, it\n");
    153     printf("                  will be an adaptive Bottleneck value.\n\n");
    154     printf("bottleneck_value: The value of the bottleneck provided either\n");
    155     printf("                  as a fixed value (e.g. 25000) or\n");
    156     printf("                  read from a file (e.g. bottleneck.txt)\n\n");
    157     printf("[-m] mode       : Mode (encoder - decoder):\n");
    158     printf("                    0 - float - float\n");
    159     printf("                    1 - float - fix\n");
    160     printf("                    2 - fix - float\n");
    161     printf("                    3 - fix - fix\n\n");
    162     printf("[-PLC]          : Test PLC packetlosses\n\n");
    163     printf("[-NB] num       : Test NB interfaces:\n");
    164     printf("                    1 - encNB\n");
    165     printf("                    2 - decNB\n\n");
    166     printf("infile          : Normal speech input file\n\n");
    167     printf("outfile         : Speech output file\n\n");
    168     printf("Example usage:\n\n");
    169     printf("./kenny.exe -I bottleneck.txt -m 1 speechIn.pcm speechOut.pcm\n\n");
    170     exit(0);
    171   }
    172 
    173   printf("--------------------START---------------------\n\n");
    174   WebRtcIsac_version(version_number);
    175   printf("iSAC FLOAT version %s \n", version_number);
    176   WebRtcIsacfix_version(version_number);
    177   printf("iSAC FIX version   %s \n\n", version_number);
    178 
    179   CodingMode = 0;
    180   tmp = 1;
    181   for (i = 1; i < argc; i++) {
    182     if (!strcmp("-I", argv[i])) {
    183       printf("\nInstantaneous BottleNeck\n");
    184       CodingMode = 1;
    185       i++;
    186       tmp = 0;
    187     }
    188 
    189     if (!strcmp("-m", argv[i])) {
    190       mode = atoi(argv[i + 1]);
    191       i++;
    192     }
    193 
    194     if (!strcmp("-PLC", argv[i])) {
    195       plc = 1;
    196     }
    197 
    198     if (!strcmp("-NB", argv[i])) {
    199       nbTest = atoi(argv[i + 1]);
    200       i++;
    201     }
    202   }
    203 
    204   if (mode < 0) {
    205     printf("\nError! Mode must be set: -m 0 \n");
    206     exit(0);
    207   }
    208 
    209   if (CodingMode == 0) {
    210     printf("\nAdaptive BottleNeck\n");
    211   }
    212 
    213   /* Get Bottleneck value */
    214   bottleneck = atoi(argv[2 - tmp]);
    215   if (bottleneck == 0) {
    216     sscanf(argv[2 - tmp], "%s", bottleneck_file);
    217     f_bn = fopen(bottleneck_file, "rb");
    218     if (f_bn == NULL) {
    219       printf("No value provided for BottleNeck and cannot read file %s.\n",
    220              bottleneck_file);
    221       exit(0);
    222     } else {
    223       printf("reading bottleneck rates from file %s\n\n", bottleneck_file);
    224       if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
    225         /* Set pointer to beginning of file */
    226         fseek(f_bn, 0L, SEEK_SET);
    227         fscanf(f_bn, "%d", &bottleneck);
    228       }
    229 
    230       /* Bottleneck is a cosine function
    231        * Matlab code for writing the bottleneck file:
    232        * BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
    233        * fid = fopen('bottleneck.txt', 'wb');
    234        * fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
    235        */
    236     }
    237   } else {
    238     printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
    239   }
    240 
    241   /* Get Input and Output files */
    242   sscanf(argv[argc - 2], "%s", inname);
    243   sscanf(argv[argc - 1], "%s", outname);
    244 
    245   if ((inp = fopen(inname, "rb")) == NULL) {
    246     printf("  iSAC: Cannot read file %s.\n", inname);
    247     exit(1);
    248   }
    249   if ((outp = fopen(outname, "wb")) == NULL) {
    250     printf("  iSAC: Cannot write file %s.\n", outname);
    251     exit(1);
    252   }
    253   printf("\nInput:%s\nOutput:%s\n", inname, outname);
    254 
    255   i = 0;
    256   while (outname[i] != '\0') {
    257     bitfilename[i] = outname[i];
    258     i++;
    259   }
    260   i -= 4;
    261   for (j = 0; j < 9; j++, i++)
    262     bitfilename[i] = bitending[j];
    263   bitfilename[i] = '\0';
    264   if ((bitsp = fopen(bitfilename, "wb")) == NULL) {
    265     printf("  iSAC: Cannot read file %s.\n", bitfilename);
    266     exit(1);
    267   }
    268   printf("Bitstream:%s\n\n", bitfilename);
    269 
    270   starttime = clock() / (double)CLOCKS_PER_SEC; /* Runtime statistics */
    271 
    272   /* Initialize the ISAC and BN structs */
    273   WebRtcIsac_create(&ISAC_main_inst);
    274   WebRtcIsacfix_Create(&ISACFIX_main_inst);
    275 
    276   BN_data.send_time = 0;
    277   BN_data.arrival_time = 0;
    278   BN_data.sample_count = 0;
    279   BN_data.rtp_number = 0;
    280 
    281   /* Initialize encoder and decoder */
    282   framecnt = 0;
    283   endfile = 0;
    284 
    285   if (mode == 0) { /* Encode using FLOAT, decode using FLOAT */
    286 
    287     printf("Coding mode: Encode using FLOAT, decode using FLOAT \n\n");
    288 
    289     /* Init iSAC FLOAT */
    290     WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
    291     WebRtcIsac_DecoderInit(ISAC_main_inst);
    292     if (CodingMode == 1) {
    293       err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
    294       if (err < 0) {
    295         /* exit if returned with error */
    296         errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    297         printf("\n\n Error in initialization: %d.\n\n", errtype);
    298         // exit(EXIT_FAILURE);
    299       }
    300     }
    301 
    302   } else if (mode == 1) { /* Encode using FLOAT, decode using FIX */
    303 
    304     printf("Coding mode: Encode using FLOAT, decode using FIX \n\n");
    305 
    306     /* Init iSAC FLOAT */
    307     WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
    308     WebRtcIsac_DecoderInit(ISAC_main_inst);
    309     if (CodingMode == 1) {
    310       err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
    311       if (err < 0) {
    312         /* exit if returned with error */
    313         errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    314         printf("\n\n Error in initialization: %d.\n\n", errtype);
    315         // exit(EXIT_FAILURE);
    316       }
    317     }
    318 
    319     /* Init iSAC FIX */
    320     WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
    321     WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
    322     if (CodingMode == 1) {
    323       err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
    324       if (err < 0) {
    325         /* exit if returned with error */
    326         errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    327         printf("\n\n Error in initialization: %d.\n\n", errtype);
    328         // exit(EXIT_FAILURE);
    329       }
    330     }
    331   } else if (mode == 2) { /* Encode using FIX, decode using FLOAT */
    332 
    333     printf("Coding mode: Encode using FIX, decode using FLOAT \n\n");
    334 
    335     /* Init iSAC FLOAT */
    336     WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
    337     WebRtcIsac_DecoderInit(ISAC_main_inst);
    338     if (CodingMode == 1) {
    339       err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
    340       if (err < 0) {
    341         /* exit if returned with error */
    342         errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    343         printf("\n\n Error in initialization: %d.\n\n", errtype);
    344         // exit(EXIT_FAILURE);
    345       }
    346     }
    347 
    348     /* Init iSAC FIX */
    349     WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
    350     WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
    351     if (CodingMode == 1) {
    352       err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
    353       if (err < 0) {
    354         /* exit if returned with error */
    355         errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    356         printf("\n\n Error in initialization: %d.\n\n", errtype);
    357         // exit(EXIT_FAILURE);
    358       }
    359     }
    360   } else if (mode == 3) {
    361     printf("Coding mode: Encode using FIX, decode using FIX \n\n");
    362 
    363     WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
    364     WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
    365     if (CodingMode == 1) {
    366       err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
    367       if (err < 0) {
    368         /* exit if returned with error */
    369         errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    370         printf("\n\n Error in initialization: %d.\n\n", errtype);
    371         // exit(EXIT_FAILURE);
    372       }
    373     }
    374 
    375   } else
    376     printf("Mode must be value between 0 and 3\n");
    377   *speechType = 1;
    378 
    379 //#define BI_TEST 1
    380 #ifdef BI_TEST
    381   err = WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_main_inst, 300);
    382   if (err < 0) {
    383     /* exit if returned with error */
    384     errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    385     printf("\n\n Error in setMaxPayloadSize: %d.\n\n", errtype);
    386     fclose(inp);
    387     fclose(outp);
    388     fclose(bitsp);
    389     return (EXIT_FAILURE);
    390   }
    391 #endif
    392 
    393   while (endfile == 0) {
    394     cur_framesmpls = 0;
    395     while (1) {
    396       int stream_len_int;
    397 
    398       /* Read 10 ms speech block */
    399       if (nbTest != 1)
    400         endfile = readframe(shortdata, inp, FRAMESAMPLES_10ms);
    401       else
    402         endfile = readframe(shortdata, inp, (FRAMESAMPLES_10ms / 2));
    403 
    404       /* iSAC encoding */
    405 
    406       if (mode == 0 || mode == 1) {
    407         stream_len_int =
    408             WebRtcIsac_Encode(ISAC_main_inst, shortdata, (uint8_t*)streamdata);
    409         if (stream_len_int < 0) {
    410           /* exit if returned with error */
    411           errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    412           printf("\n\nError in encoder: %d.\n\n", errtype);
    413           // exit(EXIT_FAILURE);
    414         }
    415       } else if (mode == 2 || mode == 3) {
    416         /* iSAC encoding */
    417         if (nbTest != 1) {
    418           stream_len_int = WebRtcIsacfix_Encode(ISACFIX_main_inst, shortdata,
    419                                                 (uint8_t*)streamdata);
    420         } else {
    421           stream_len_int =
    422               WebRtcIsacfix_EncodeNb(ISACFIX_main_inst, shortdata, streamdata);
    423         }
    424 
    425         if (stream_len_int < 0) {
    426           /* exit if returned with error */
    427           errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    428           printf("\n\nError in encoder: %d.\n\n", errtype);
    429           // exit(EXIT_FAILURE);
    430         }
    431       }
    432       stream_len = (size_t)stream_len_int;
    433 
    434       cur_framesmpls += FRAMESAMPLES_10ms;
    435 
    436       /* read next bottleneck rate */
    437       if (f_bn != NULL) {
    438         if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
    439           /* Set pointer to beginning of file */
    440           fseek(f_bn, 0L, SEEK_SET);
    441           fscanf(f_bn, "%d", &bottleneck);
    442         }
    443         if (CodingMode == 1) {
    444           if (mode == 0 || mode == 1)
    445             WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
    446           else if (mode == 2 || mode == 3)
    447             WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
    448         }
    449       }
    450 
    451       /* exit encoder loop if the encoder returned a bitstream */
    452       if (stream_len != 0)
    453         break;
    454     }
    455 
    456     fwrite(streamdata, 1, stream_len, bitsp); /* NOTE! Writes bytes to file */
    457 
    458     /* simulate packet handling through NetEq and the modem */
    459     get_arrival_time(cur_framesmpls, stream_len, bottleneck, &BN_data);
    460     //*****************************
    461     if (1) {
    462       if (mode == 0) {
    463         err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst, streamdata,
    464                                           stream_len, BN_data.rtp_number,
    465                                           BN_data.arrival_time);
    466 
    467         if (err < 0) {
    468           /* exit if returned with error */
    469           errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    470           printf("\n\nError in decoder: %d.\n\n", errtype);
    471           // exit(EXIT_FAILURE);
    472         }
    473         /* iSAC decoding */
    474         declen = WebRtcIsac_Decode(ISAC_main_inst, streamdata, stream_len,
    475                                    decoded, speechType);
    476         if (declen <= 0) {
    477           /* exit if returned with error */
    478           errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    479           printf("\n\nError in decoder: %d.\n\n", errtype);
    480           // exit(EXIT_FAILURE);
    481         }
    482       } else if (mode == 1) {
    483         err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst, streamdata,
    484                                           stream_len, BN_data.rtp_number,
    485                                           BN_data.arrival_time);
    486         err = WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_main_inst, streamdata,
    487                                               stream_len, BN_data.rtp_number,
    488                                               BN_data.arrival_time);
    489         if (err < 0) {
    490           /* exit if returned with error */
    491           errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    492           printf("\n\nError in decoder: %d.\n\n", errtype);
    493           // exit(EXIT_FAILURE);
    494         }
    495 
    496         declen = WebRtcIsac_Decode(ISAC_main_inst, streamdata, stream_len,
    497                                    decoded, speechType);
    498 
    499         /* iSAC decoding */
    500         if (plc && (framecnt + 1) % 10 == 0) {
    501           if (nbTest != 2) {
    502             declen =
    503                 (int)WebRtcIsacfix_DecodePlc(ISACFIX_main_inst, decoded, 1);
    504           } else {
    505             declen =
    506                 (int)WebRtcIsacfix_DecodePlcNb(ISACFIX_main_inst, decoded, 1);
    507           }
    508         } else {
    509           if (nbTest != 2)
    510             declen = WebRtcIsacfix_Decode(ISACFIX_main_inst, streamdata,
    511                                           stream_len, decoded, speechType);
    512           else
    513             declen = WebRtcIsacfix_DecodeNb(ISACFIX_main_inst, streamdata,
    514                                             stream_len, decoded, speechType);
    515         }
    516 
    517         if (declen <= 0) {
    518           /* exit if returned with error */
    519           errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    520           printf("\n\nError in decoder: %d.\n\n", errtype);
    521           // exit(EXIT_FAILURE);
    522         }
    523       } else if (mode == 2) {
    524         err = WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_main_inst, streamdata,
    525                                               stream_len, BN_data.rtp_number,
    526                                               BN_data.arrival_time);
    527 
    528         err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst, streamdata,
    529                                           stream_len, BN_data.rtp_number,
    530                                           BN_data.arrival_time);
    531 
    532         if (err < 0) {
    533           /* exit if returned with error */
    534           errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    535           printf("\n\nError in decoder: %d.\n\n", errtype);
    536           // exit(EXIT_FAILURE);
    537         }
    538         /* iSAC decoding */
    539         declen = WebRtcIsac_Decode(ISAC_main_inst, streamdata, stream_len,
    540                                    decoded, speechType);
    541         if (declen <= 0) {
    542           /* exit if returned with error */
    543           errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
    544           printf("\n\nError in decoder: %d.\n\n", errtype);
    545           // exit(EXIT_FAILURE);
    546         }
    547       } else if (mode == 3) {
    548         err = WebRtcIsacfix_UpdateBwEstimate(
    549             ISACFIX_main_inst, streamdata, stream_len, BN_data.rtp_number,
    550             BN_data.send_time, BN_data.arrival_time);
    551 
    552         if (err < 0) {
    553           /* exit if returned with error */
    554           errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    555           printf("\n\nError in decoder: %d.\n\n", errtype);
    556           // exit(EXIT_FAILURE);
    557         }
    558         /* iSAC decoding */
    559 
    560         if (plc && (framecnt + 1) % 10 == 0) {
    561           if (nbTest != 2) {
    562             declen =
    563                 (int)WebRtcIsacfix_DecodePlc(ISACFIX_main_inst, decoded, 1);
    564           } else {
    565             declen =
    566                 (int)WebRtcIsacfix_DecodePlcNb(ISACFIX_main_inst, decoded, 1);
    567           }
    568         } else {
    569           if (nbTest != 2) {
    570             declen = WebRtcIsacfix_Decode(ISACFIX_main_inst, streamdata,
    571                                           stream_len, decoded, speechType);
    572           } else {
    573             declen = WebRtcIsacfix_DecodeNb(ISACFIX_main_inst, streamdata,
    574                                             stream_len, decoded, speechType);
    575           }
    576         }
    577         if (declen <= 0) {
    578           /* exit if returned with error */
    579           errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
    580           printf("\n\nError in decoder: %d.\n\n", errtype);
    581           // exit(EXIT_FAILURE);
    582         }
    583       }
    584 
    585       /* Write decoded speech frame to file */
    586       fwrite(decoded, sizeof(int16_t), declen, outp);
    587     }
    588 
    589     fprintf(stderr, "  \rframe = %d", framecnt);
    590     framecnt++;
    591 
    592 #if !defined(NDEBUG)
    593 
    594     totalsmpls += declen;
    595     totalbits += 8 * stream_len;
    596     kbps = (double)FS / (double)cur_framesmpls * 8.0 * stream_len / 1000.0;
    597     fy = fopen("bit_rate.dat", "a");
    598     fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
    599     fclose(fy);
    600 
    601 #endif
    602   }
    603 
    604 #if !defined(NDEBUG)
    605   printf("\n\ntotal bits               = %" PRIuS " bits", totalbits);
    606   printf("\nmeasured average bitrate = %0.3f kbits/s",
    607          (double)totalbits * (FS / 1000) / totalsmpls);
    608   printf("\n");
    609 #endif
    610 
    611   /* Runtime statistics */
    612   runtime = (double)(clock() / (double)CLOCKS_PER_SEC - starttime);
    613   length_file = ((double)framecnt * (double)declen / FS);
    614   printf("\n\nLength of speech file: %.1f s\n", length_file);
    615   printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n", runtime,
    616          (100 * runtime / length_file));
    617   printf("---------------------END----------------------\n");
    618 
    619   fclose(inp);
    620   fclose(outp);
    621 
    622   WebRtcIsac_Free(ISAC_main_inst);
    623   WebRtcIsacfix_Free(ISACFIX_main_inst);
    624 
    625   // fclose(histfile);
    626   // fclose(ratefile);
    627 
    628   return 0;
    629 }
    630