ReleaseTest-API.cc revision b7e5054414ff524f9db81dab7917729b8c4c8bcb
1/*
2 *  Copyright (c) 2012 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// ReleaseTest-API.cpp : Defines the entry point for the console application.
12//
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include <time.h>
18#include <ctype.h>
19#include <iostream>
20
21/* include API */
22#include "isac.h"
23#include "utility.h"
24
25/* Defines */
26#define SEED_FILE "randseed.txt" /* Used when running decoder on garbage data */
27#define MAX_FRAMESAMPLES 960     /* max number of samples per frame
28                                    (= 60 ms frame & 16 kHz) or
29                                    (= 30 ms frame & 32 kHz) */
30#define FRAMESAMPLES_10ms 160 /* number of samples per 10ms frame */
31#define SWBFRAMESAMPLES_10ms 320
32//#define FS 16000 /* sampling frequency (Hz) */
33
34#ifdef WIN32
35#define CLOCKS_PER_SEC 1000 /* Runtime statistics */
36#endif
37
38using namespace std;
39
40int main(int argc, char* argv[]) {
41  char inname[100], outname[100], bottleneck_file[100], vadfile[100];
42  FILE* inp, *outp, * f_bn = NULL, * vadp = NULL, *bandwidthp;
43  int framecnt, endfile;
44
45  int i, errtype, VADusage = 0, packetLossPercent = 0;
46  int16_t CodingMode;
47  int32_t bottleneck = 0;
48  int16_t framesize = 30; /* ms */
49  int cur_framesmpls, err;
50
51  /* Runtime statistics */
52  double starttime, runtime, length_file;
53
54  int16_t stream_len = 0;
55  int16_t declen = 0, declenTC = 0;
56  bool lostFrame = false;
57
58  int16_t shortdata[SWBFRAMESAMPLES_10ms];
59  int16_t vaddata[SWBFRAMESAMPLES_10ms * 3];
60  int16_t decoded[MAX_FRAMESAMPLES << 1];
61  int16_t decodedTC[MAX_FRAMESAMPLES << 1];
62  uint16_t streamdata[500];
63  int16_t speechType[1];
64  int16_t rateBPS = 0;
65  int16_t fixedFL = 0;
66  int16_t payloadSize = 0;
67  int32_t payloadRate = 0;
68  int setControlBWE = 0;
69  short FL, testNum;
70  char version_number[20];
71  FILE* plFile;
72  int32_t sendBN;
73
74#ifdef _DEBUG
75  FILE* fy;
76  double kbps;
77#endif /* _DEBUG */
78  int totalbits = 0;
79  int totalsmpls = 0;
80
81  /* If use GNS file */
82  FILE* fp_gns = NULL;
83  char gns_file[100];
84  short maxStreamLen30 = 0;
85  short maxStreamLen60 = 0;
86  short sampFreqKHz = 32;
87  short samplesIn10Ms;
88  short useAssign = 0;
89  // FILE logFile;
90  bool doTransCoding = false;
91  int32_t rateTransCoding = 0;
92  uint8_t streamDataTransCoding[1200];
93  int16_t streamLenTransCoding = 0;
94  FILE* transCodingFile = NULL;
95  FILE* transcodingBitstream = NULL;
96  uint32_t numTransCodingBytes = 0;
97
98  /* only one structure used for ISAC encoder */
99  ISACStruct* ISAC_main_inst = NULL;
100  ISACStruct* decoderTransCoding = NULL;
101
102  BottleNeckModel BN_data;
103
104#ifdef _DEBUG
105  fy = fopen("bit_rate.dat", "w");
106  fclose(fy);
107  fy = fopen("bytes_frames.dat", "w");
108  fclose(fy);
109#endif /* _DEBUG */
110
111  /* Handling wrong input arguments in the command line */
112  if ((argc < 3) || (argc > 17)) {
113    printf("\n\nWrong number of arguments or flag values.\n\n");
114
115    printf("\n");
116    WebRtcIsac_version(version_number);
117    printf("iSAC-swb version %s \n\n", version_number);
118
119    printf("Usage:\n\n");
120    printf("./kenny.exe [-I] bottleneck_value infile outfile \n\n");
121    printf("with:\n");
122    printf("[-FS num]       : sampling frequency in kHz, valid values are\n");
123    printf("                  16 & 32, with 16 as default.\n");
124    printf("[-I]            : if -I option is specified, the coder will use\n");
125    printf("                  an instantaneous Bottleneck value. If not, it\n");
126    printf("                  will be an adaptive Bottleneck value.\n");
127    printf("[-assign]       : Use Assign API.\n");
128    printf("[-B num]        : the value of the bottleneck provided either\n");
129    printf("                  as a fixed value in bits/sec (e.g. 25000) or\n");
130    printf("                  read from a file (e.g. bottleneck.txt)\n");
131    printf("[-INITRATE num] : Set a new value for initial rate. Note! Only\n");
132    printf("                  used in adaptive mode.\n");
133    printf("[-FL num]       : Set (initial) frame length in msec. Valid\n");
134    printf("                  lengths are 30 and 60 msec.\n");
135    printf("[-FIXED_FL]     : Frame length will be fixed to initial value.\n");
136    printf("[-MAX num]      : Set the limit for the payload size of iSAC\n");
137    printf("                  in bytes. Minimum 100 maximum 400.\n");
138    printf("[-MAXRATE num]  : Set the maxrate for iSAC in bits per second.\n");
139    printf("                  Minimum 32000, maximum 53400.\n");
140    printf("[-F num]        : if -F option is specified, the test function\n");
141    printf("                  will run the iSAC API fault scenario\n");
142    printf("                  specified by the supplied number.\n");
143    printf("                  F 1 - Call encoder prior to init encoder call\n");
144    printf("                  F 2 - Call decoder prior to init decoder call\n");
145    printf("                  F 3 - Call decoder prior to encoder call\n");
146    printf("                  F 4 - Call decoder with a too short coded\n");
147    printf("                        sequence\n");
148    printf("                  F 5 - Call decoder with a too long coded\n");
149    printf("                        sequence\n");
150    printf("                  F 6 - Call decoder with random bit stream\n");
151    printf("                  F 7 - Call init encoder/decoder at random\n");
152    printf("                        during a call\n");
153    printf("                  F 8 - Call encoder/decoder without having\n");
154    printf("                        allocated memory for encoder/decoder\n");
155    printf("                        instance\n");
156    printf("                  F 9 - Call decodeB without calling decodeA\n");
157    printf("                  F 10 - Call decodeB with garbage data\n");
158    printf("[-PL num]       : if -PL option is specified \n");
159    printf("[-T rate file]  : test trans-coding with target bottleneck\n");
160    printf("                  'rate' bits/sec\n");
161    printf("                  the output file is written to 'file'\n");
162    printf("[-LOOP num]     : number of times to repeat coding the input\n");
163    printf("                  file for stress testing\n");
164    // printf("[-CE num]       : Test of APIs used by Conference Engine.\n");
165    // printf("                  CE 1 - getNewBitstream, getBWE \n");
166    // printf("                  (CE 2 - RESERVED for transcoding)\n");
167    // printf("                  CE 3 - getSendBWE, setSendBWE.  \n");
168    // printf("-L filename     : write the logging info into file
169    // (appending)\n");
170    printf("infile          :   Normal speech input file\n");
171    printf("outfile         :   Speech output file\n");
172    exit(0);
173  }
174
175  /* Print version number */
176  printf("-------------------------------------------------\n");
177  WebRtcIsac_version(version_number);
178  printf("iSAC version %s \n\n", version_number);
179
180  /* Loop over all command line arguments */
181  CodingMode = 0;
182  testNum = 0;
183  useAssign = 0;
184  // logFile = NULL;
185  char transCodingFileName[500];
186  int16_t totFileLoop = 0;
187  int16_t numFileLoop = 0;
188  for (i = 1; i + 2 < argc; i++) {
189    if (!strcmp("-LOOP", argv[i])) {
190      i++;
191      totFileLoop = (int16_t)atol(argv[i]);
192      if (totFileLoop <= 0) {
193        fprintf(stderr, "Invalid number of runs for the given input file, %d.",
194                totFileLoop);
195        exit(0);
196      }
197    }
198
199    if (!strcmp("-T", argv[i])) {
200      doTransCoding = true;
201      i++;
202      rateTransCoding = atoi(argv[i]);
203      i++;
204      strcpy(transCodingFileName, argv[i]);
205    }
206
207    /*Should we use assign API*/
208    if (!strcmp("-assign", argv[i])) {
209      useAssign = 1;
210    }
211
212    /* Set Sampling Rate */
213    if (!strcmp("-FS", argv[i])) {
214      i++;
215      sampFreqKHz = atoi(argv[i]);
216    }
217
218    /* Instantaneous mode */
219    if (!strcmp("-I", argv[i])) {
220      printf("Instantaneous BottleNeck\n");
221      CodingMode = 1;
222    }
223
224    /* Set (initial) bottleneck value */
225    if (!strcmp("-INITRATE", argv[i])) {
226      rateBPS = atoi(argv[i + 1]);
227      setControlBWE = 1;
228      if ((rateBPS < 10000) || (rateBPS > 32000)) {
229        printf("\n%d is not a initial rate. Valid values are in the range "
230               "10000 to 32000.\n", rateBPS);
231        exit(0);
232      }
233      printf("New initial rate: %d\n", rateBPS);
234      i++;
235    }
236
237    /* Set (initial) framelength */
238    if (!strcmp("-FL", argv[i])) {
239      framesize = atoi(argv[i + 1]);
240      if ((framesize != 30) && (framesize != 60)) {
241        printf("\n%d is not a valid frame length. Valid length are 30 and 60 "
242               "msec.\n", framesize);
243        exit(0);
244      }
245      setControlBWE = 1;
246      printf("Frame Length: %d\n", framesize);
247      i++;
248    }
249
250    /* Fixed frame length */
251    if (!strcmp("-FIXED_FL", argv[i])) {
252      fixedFL = 1;
253      setControlBWE = 1;
254      printf("Fixed Frame Length\n");
255    }
256
257    /* Set maximum allowed payload size in bytes */
258    if (!strcmp("-MAX", argv[i])) {
259      payloadSize = atoi(argv[i + 1]);
260      printf("Maximum Payload Size: %d\n", payloadSize);
261      i++;
262    }
263
264    /* Set maximum rate in bytes */
265    if (!strcmp("-MAXRATE", argv[i])) {
266      payloadRate = atoi(argv[i + 1]);
267      printf("Maximum Rate in kbps: %d\n", payloadRate);
268      i++;
269    }
270
271    /* Test of fault scenarious */
272    if (!strcmp("-F", argv[i])) {
273      testNum = atoi(argv[i + 1]);
274      printf("Fault test: %d\n", testNum);
275      if (testNum < 1 || testNum > 10) {
276        printf("\n%d is not a valid Fault Scenario number. Valid Fault "
277               "Scenarios are numbered 1-10.\n", testNum);
278        exit(0);
279      }
280      i++;
281    }
282
283    /* Packet loss test */
284    if (!strcmp("-PL", argv[i])) {
285      if (isdigit(*argv[i + 1])) {
286        packetLossPercent = atoi(argv[i + 1]);
287        if ((packetLossPercent < 0) | (packetLossPercent > 100)) {
288          printf("\nInvalid packet loss perentage \n");
289          exit(0);
290        }
291        if (packetLossPercent > 0) {
292          printf("Simulating %d %% of independent packet loss\n",
293                 packetLossPercent);
294        } else {
295          printf("\nNo Packet Loss Is Simulated \n");
296        }
297      } else {
298        plFile = fopen(argv[i + 1], "rb");
299        if (plFile == NULL) {
300          printf("\n couldn't open the frameloss file: %s\n", argv[i + 1]);
301          exit(0);
302        }
303        printf("Simulating packet loss through the given channel file: %s\n",
304               argv[i + 1]);
305      }
306      i++;
307    }
308
309    /* Random packetlosses */
310    if (!strcmp("-rnd", argv[i])) {
311      srand((unsigned int)time(NULL));
312      printf("Random pattern in lossed packets \n");
313    }
314
315    /* Use gns file */
316    if (!strcmp("-G", argv[i])) {
317      sscanf(argv[i + 1], "%s", gns_file);
318      fp_gns = fopen(gns_file, "rb");
319      if (fp_gns == NULL) {
320        printf("Cannot read file %s.\n", gns_file);
321        exit(0);
322      }
323      i++;
324    }
325
326    // make it with '-B'
327    /* Get Bottleneck value */
328    if (!strcmp("-B", argv[i])) {
329      i++;
330      bottleneck = atoi(argv[i]);
331      if (bottleneck == 0) {
332        sscanf(argv[i], "%s", bottleneck_file);
333        f_bn = fopen(bottleneck_file, "rb");
334        if (f_bn == NULL) {
335          printf("Error No value provided for BottleNeck and cannot read file "
336                 "%s.\n", bottleneck_file);
337          exit(0);
338        } else {
339          printf("reading bottleneck rates from file %s\n\n", bottleneck_file);
340          if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
341            /* Set pointer to beginning of file */
342            fseek(f_bn, 0L, SEEK_SET);
343            if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
344              exit(0);
345            }
346          }
347
348          /* Bottleneck is a cosine function
349           * Matlab code for writing the bottleneck file:
350           * BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
351           * fid = fopen('bottleneck.txt', 'wb');
352           * fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
353           */
354        }
355      } else {
356        printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
357      }
358    }
359    /* Run Conference Engine APIs */
360    //     Do not test it in the first release
361    //
362    //     if(!strcmp ("-CE", argv[i]))
363    //     {
364    //         testCE = atoi(argv[i + 1]);
365    //         if(testCE==1)
366    //         {
367    //             i++;
368    //             scale = (float)atof( argv[i+1] );
369    //         }
370    //         else if(testCE == 2)
371    //         {
372    //             printf("\nCE-test 2 (transcoding) not implemented.\n");
373    //             exit(0);
374    //         }
375    //         else if(testCE < 1 || testCE > 3)
376    //         {
377    //             printf("\n%d is not a valid CE-test number. Valid CE tests
378    //             are 1-3.\n", testCE);
379    //             exit(0);
380    //         }
381    //         printf("CE-test number: %d\n", testCE);
382    //         i++;
383    //     }
384  }
385
386  if (CodingMode == 0) {
387    printf("\nAdaptive BottleNeck\n");
388  }
389
390  switch (sampFreqKHz) {
391    case 16: {
392      printf("iSAC Wideband.\n");
393      samplesIn10Ms = FRAMESAMPLES_10ms;
394      break;
395    }
396    case 32: {
397      printf("iSAC Supper-Wideband.\n");
398      samplesIn10Ms = SWBFRAMESAMPLES_10ms;
399      break;
400    }
401    default:
402      printf("Unsupported sampling frequency %d kHz", sampFreqKHz);
403      exit(0);
404  }
405
406  /* Get Input and Output files */
407  sscanf(argv[argc - 2], "%s", inname);
408  sscanf(argv[argc - 1], "%s", outname);
409  printf("\nInput file: %s\n", inname);
410  printf("Output file: %s\n\n", outname);
411  if ((inp = fopen(inname, "rb")) == NULL) {
412    printf("  Error iSAC Cannot read file %s.\n", inname);
413    cout << flush;
414    exit(1);
415  }
416
417  if ((outp = fopen(outname, "wb")) == NULL) {
418    printf("  Error iSAC Cannot write file %s.\n", outname);
419    cout << flush;
420    getc(stdin);
421    exit(1);
422  }
423  if (VADusage) {
424    if ((vadp = fopen(vadfile, "rb")) == NULL) {
425      printf("  Error iSAC Cannot read file %s.\n", vadfile);
426      cout << flush;
427      exit(1);
428    }
429  }
430
431  if ((bandwidthp = fopen("bwe.pcm", "wb")) == NULL) {
432    printf("  Error iSAC Cannot read file %s.\n", "bwe.pcm");
433    cout << flush;
434    exit(1);
435  }
436
437  starttime = clock() / (double)CLOCKS_PER_SEC; /* Runtime statistics */
438
439  /* Initialize the ISAC and BN structs */
440  if (testNum != 8) {
441    if (!useAssign) {
442      err = WebRtcIsac_Create(&ISAC_main_inst);
443      WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000);
444      WebRtcIsac_SetDecSampRate(ISAC_main_inst,
445                                sampFreqKHz >= 32 ? 32000 : 16000);
446    } else {
447      /* Test the Assign functions */
448      int sss;
449      void* ppp;
450      err = WebRtcIsac_AssignSize(&sss);
451      ppp = malloc(sss);
452      err = WebRtcIsac_Assign(&ISAC_main_inst, ppp);
453      WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000);
454      WebRtcIsac_SetDecSampRate(ISAC_main_inst,
455                                sampFreqKHz >= 32 ? 32000 : 16000);
456    }
457    /* Error check */
458    if (err < 0) {
459      printf("\n\n Error in create.\n\n");
460      cout << flush;
461      exit(EXIT_FAILURE);
462    }
463  }
464  BN_data.arrival_time = 0;
465  BN_data.sample_count = 0;
466  BN_data.rtp_number = 0;
467
468  /* Initialize encoder and decoder */
469  framecnt = 0;
470  endfile = 0;
471
472  if (doTransCoding) {
473    WebRtcIsac_Create(&decoderTransCoding);
474    WebRtcIsac_SetEncSampRate(decoderTransCoding, sampFreqKHz * 1000);
475    WebRtcIsac_SetDecSampRate(decoderTransCoding,
476                              sampFreqKHz >= 32 ? 32000 : 16000);
477    WebRtcIsac_DecoderInit(decoderTransCoding);
478    transCodingFile = fopen(transCodingFileName, "wb");
479    if (transCodingFile == NULL) {
480      printf("Could not open %s to output trans-coding.\n",
481             transCodingFileName);
482      exit(0);
483    }
484    strcat(transCodingFileName, ".bit");
485    transcodingBitstream = fopen(transCodingFileName, "wb");
486    if (transcodingBitstream == NULL) {
487      printf("Could not open %s to write the bit-stream of transcoder.\n",
488             transCodingFileName);
489      exit(0);
490    }
491  }
492
493  if (testNum != 1) {
494    if (WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode) < 0) {
495      printf("Error could not initialize the encoder \n");
496      cout << flush;
497      return 0;
498    }
499  }
500  if (testNum != 2) {
501    if (WebRtcIsac_DecoderInit(ISAC_main_inst) < 0) {
502      printf("Error could not initialize the decoder \n");
503      cout << flush;
504      return 0;
505    }
506  }
507  if (CodingMode == 1) {
508    err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
509    if (err < 0) {
510      /* exit if returned with error */
511      errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
512      printf("\n\n Error in initialization (control): %d.\n\n", errtype);
513      cout << flush;
514      if (testNum == 0) {
515        exit(EXIT_FAILURE);
516      }
517    }
518  }
519
520  if ((setControlBWE) && (CodingMode == 0)) {
521    err = WebRtcIsac_ControlBwe(ISAC_main_inst, rateBPS, framesize, fixedFL);
522    if (err < 0) {
523      /* exit if returned with error */
524      errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
525
526      printf("\n\n Error in Control BWE: %d.\n\n", errtype);
527      cout << flush;
528      exit(EXIT_FAILURE);
529    }
530  }
531
532  if (payloadSize != 0) {
533    err = WebRtcIsac_SetMaxPayloadSize(ISAC_main_inst, payloadSize);
534    if (err < 0) {
535      /* exit if returned with error */
536      errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
537      printf("\n\n Error in SetMaxPayloadSize: %d.\n\n", errtype);
538      cout << flush;
539      exit(EXIT_FAILURE);
540    }
541  }
542  if (payloadRate != 0) {
543    err = WebRtcIsac_SetMaxRate(ISAC_main_inst, payloadRate);
544    if (err < 0) {
545      /* exit if returned with error */
546      errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
547      printf("\n\n Error in SetMaxRateInBytes: %d.\n\n", errtype);
548      cout << flush;
549      exit(EXIT_FAILURE);
550    }
551  }
552
553  *speechType = 1;
554
555  cout << "\n" << flush;
556
557  length_file = 0;
558  int16_t bnIdxTC = 0;
559  int16_t jitterInfoTC = 0;
560  while (endfile == 0) {
561    /* Call init functions at random, fault test number 7 */
562    if (testNum == 7 && (rand() % 2 == 0)) {
563      err = WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
564      /* Error check */
565      if (err < 0) {
566        errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
567        printf("\n\n Error in encoderinit: %d.\n\n", errtype);
568        cout << flush;
569      }
570
571      err = WebRtcIsac_DecoderInit(ISAC_main_inst);
572      /* Error check */
573      if (err < 0) {
574        errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
575        printf("\n\n Error in decoderinit: %d.\n\n", errtype);
576        cout << flush;
577      }
578    }
579
580    cur_framesmpls = 0;
581    while (1) {
582      /* Read 10 ms speech block */
583      endfile = readframe(shortdata, inp, samplesIn10Ms);
584
585      if (endfile) {
586        numFileLoop++;
587        if (numFileLoop < totFileLoop) {
588          rewind(inp);
589          framecnt = 0;
590          fprintf(stderr, "\n");
591          endfile = readframe(shortdata, inp, samplesIn10Ms);
592        }
593      }
594
595      if (testNum == 7) {
596        srand((unsigned int)time(NULL));
597      }
598
599      /* iSAC encoding */
600      if (!(testNum == 3 && framecnt == 0)) {
601        stream_len =
602            WebRtcIsac_Encode(ISAC_main_inst, shortdata, (uint8_t*)streamdata);
603        if ((payloadSize != 0) && (stream_len > payloadSize)) {
604          if (testNum == 0) {
605            printf("\n\n");
606          }
607
608          printf("\nError: Streamsize out of range %d\n",
609                 stream_len - payloadSize);
610          cout << flush;
611        }
612
613        WebRtcIsac_GetUplinkBw(ISAC_main_inst, &sendBN);
614
615        if (stream_len > 0) {
616          if (doTransCoding) {
617            int16_t indexStream;
618            uint8_t auxUW8;
619
620            /******************** Main Transcoding stream ********************/
621            WebRtcIsac_GetDownLinkBwIndex(ISAC_main_inst, &bnIdxTC,
622                                          &jitterInfoTC);
623            streamLenTransCoding = WebRtcIsac_GetNewBitStream(
624                ISAC_main_inst, bnIdxTC, jitterInfoTC, rateTransCoding,
625                streamDataTransCoding, false);
626            if (streamLenTransCoding < 0) {
627              fprintf(stderr, "Error in trans-coding\n");
628              exit(0);
629            }
630            auxUW8 = (uint8_t)(((streamLenTransCoding & 0xFF00) >> 8) & 0x00FF);
631            if (fwrite(&auxUW8, sizeof(uint8_t), 1, transcodingBitstream) !=
632                1) {
633              return -1;
634            }
635
636            auxUW8 = (uint8_t)(streamLenTransCoding & 0x00FF);
637            if (fwrite(&auxUW8, sizeof(uint8_t), 1, transcodingBitstream) !=
638                1) {
639              return -1;
640            }
641
642            if (fwrite(streamDataTransCoding, sizeof(uint8_t),
643                       streamLenTransCoding, transcodingBitstream) !=
644                static_cast<size_t>(streamLenTransCoding)) {
645              return -1;
646            }
647
648            WebRtcIsac_ReadBwIndex(streamDataTransCoding, &indexStream);
649            if (indexStream != bnIdxTC) {
650              fprintf(stderr,
651                      "Error in inserting Bandwidth index into transcoding "
652                      "stream.\n");
653              exit(0);
654            }
655            numTransCodingBytes += streamLenTransCoding;
656          }
657        }
658      } else {
659        break;
660      }
661
662      if (stream_len < 0) {
663        /* exit if returned with error */
664        errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
665        printf("\n\nError in encoder: %d.\n\n", errtype);
666        cout << flush;
667      }
668      cur_framesmpls += samplesIn10Ms;
669      /* exit encoder loop if the encoder returned a bitstream */
670      if (stream_len != 0)
671        break;
672    }
673
674    /* read next bottleneck rate */
675    if (f_bn != NULL) {
676      if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
677        /* Set pointer to beginning of file */
678        fseek(f_bn, 0L, SEEK_SET);
679        if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
680          exit(0);
681        }
682      }
683      if (CodingMode == 1) {
684        WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
685      }
686    }
687
688    length_file += cur_framesmpls;
689    if (cur_framesmpls == (3 * samplesIn10Ms)) {
690      maxStreamLen30 =
691          (stream_len > maxStreamLen30) ? stream_len : maxStreamLen30;
692    } else {
693      maxStreamLen60 =
694          (stream_len > maxStreamLen60) ? stream_len : maxStreamLen60;
695    }
696
697    if (!lostFrame) {
698      lostFrame = ((rand() % 100) < packetLossPercent);
699    } else {
700      lostFrame = false;
701    }
702
703    // RED.
704    if (lostFrame) {
705      stream_len = WebRtcIsac_GetRedPayload(
706          ISAC_main_inst, reinterpret_cast<uint8_t*>(streamdata));
707
708      if (doTransCoding) {
709        streamLenTransCoding = WebRtcIsac_GetNewBitStream(
710            ISAC_main_inst, bnIdxTC, jitterInfoTC, rateTransCoding,
711            streamDataTransCoding, true);
712        if (streamLenTransCoding < 0) {
713          fprintf(stderr, "Error in RED trans-coding\n");
714          exit(0);
715        }
716      }
717    }
718
719    /* make coded sequence to short be inreasing */
720    /* the length the decoder expects */
721    if (testNum == 4) {
722      stream_len += 10;
723    }
724
725    /* make coded sequence to long be decreasing */
726    /* the length the decoder expects */
727    if (testNum == 5) {
728      stream_len -= 10;
729    }
730
731    if (testNum == 6) {
732      srand((unsigned int)time(NULL));
733      for (i = 0; i < stream_len; i++) {
734        streamdata[i] = rand();
735      }
736    }
737
738    if (VADusage) {
739      readframe(vaddata, vadp, samplesIn10Ms * 3);
740    }
741
742    /* simulate packet handling through NetEq and the modem */
743    if (!(testNum == 3 && framecnt == 0)) {
744      get_arrival_time(cur_framesmpls, stream_len, bottleneck, &BN_data,
745                       sampFreqKHz * 1000, sampFreqKHz * 1000);
746    }
747
748    if (VADusage && (framecnt > 10 && vaddata[0] == 0)) {
749      BN_data.rtp_number--;
750    } else {
751      /* Error test number 10, garbage data */
752      if (testNum == 10) {
753        /* Test to run decoder with garbage data */
754        for (i = 0; i < stream_len; i++) {
755          streamdata[i] = (short)(streamdata[i]) + (short)rand();
756        }
757      }
758
759      if (testNum != 9) {
760        err = WebRtcIsac_UpdateBwEstimate(
761            ISAC_main_inst, reinterpret_cast<const uint8_t*>(streamdata),
762            stream_len, BN_data.rtp_number, BN_data.sample_count,
763            BN_data.arrival_time);
764
765        if (err < 0) {
766          /* exit if returned with error */
767          errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
768          if (testNum == 0) {
769            printf("\n\n");
770          }
771
772          printf("Error: in decoder: %d.", errtype);
773          cout << flush;
774          if (testNum == 0) {
775            printf("\n\n");
776          }
777        }
778      }
779
780      /* Call getFramelen, only used here for function test */
781      err = WebRtcIsac_ReadFrameLen(
782          ISAC_main_inst, reinterpret_cast<const uint8_t*>(streamdata), &FL);
783      if (err < 0) {
784        /* exit if returned with error */
785        errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
786        if (testNum == 0) {
787          printf("\n\n");
788        }
789        printf("    Error: in getFrameLen %d.", errtype);
790        cout << flush;
791        if (testNum == 0) {
792          printf("\n\n");
793        }
794      }
795
796      // iSAC decoding
797
798      if (lostFrame) {
799        declen = WebRtcIsac_DecodeRcu(
800            ISAC_main_inst, reinterpret_cast<const uint8_t*>(streamdata),
801            stream_len, decoded, speechType);
802
803        if (doTransCoding) {
804          declenTC =
805              WebRtcIsac_DecodeRcu(decoderTransCoding, streamDataTransCoding,
806                                   streamLenTransCoding, decodedTC, speechType);
807        }
808      } else {
809        declen = WebRtcIsac_Decode(ISAC_main_inst,
810                                   reinterpret_cast<const uint8_t*>(streamdata),
811                                   stream_len, decoded, speechType);
812        if (doTransCoding) {
813          declenTC =
814              WebRtcIsac_Decode(decoderTransCoding, streamDataTransCoding,
815                                streamLenTransCoding, decodedTC, speechType);
816        }
817      }
818
819      if (declen < 0) {
820        /* exit if returned with error */
821        errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
822        if (testNum == 0) {
823          printf("\n\n");
824        }
825        printf("    Error: in decoder %d.", errtype);
826        cout << flush;
827        if (testNum == 0) {
828          printf("\n\n");
829        }
830      }
831
832      if (declenTC < 0) {
833        if (testNum == 0) {
834          printf("\n\n");
835        }
836        printf("    Error: in decoding the transcoded stream");
837        cout << flush;
838        if (testNum == 0) {
839          printf("\n\n");
840        }
841      }
842    }
843    /* Write decoded speech frame to file */
844    if ((declen > 0) && (numFileLoop == 0)) {
845      if (fwrite(decoded, sizeof(int16_t), declen, outp) !=
846          static_cast<size_t>(declen)) {
847        return -1;
848      }
849    }
850
851    if ((declenTC > 0) && (numFileLoop == 0)) {
852      if (fwrite(decodedTC, sizeof(int16_t), declen, transCodingFile) !=
853          static_cast<size_t>(declen)) {
854        return -1;
855      }
856    }
857
858    fprintf(stderr, "\rframe = %5d  ", framecnt);
859    fflush(stderr);
860    framecnt++;
861
862    /* Error test number 10, garbage data */
863    // if (testNum == 10)
864    // {
865    //   /* Test to run decoder with garbage data */
866    //   if ((seedfile = fopen(SEED_FILE, "a+t")) == NULL) {
867    //     fprintf(stderr, "Error: Could not open file %s\n", SEED_FILE);
868    //   } else {
869    //     fprintf(seedfile, "ok\n\n");
870    //     fclose(seedfile);
871    //   }
872    // }
873    /* Error test number 10, garbage data */
874    // if (testNum == 10) {
875    //   /* Test to run decoder with garbage data */
876    //   for (i = 0; i < stream_len; i++) {
877    //     streamdata[i] = (short) (streamdata[i] + (short) rand());
878    //   }
879    // }
880
881    totalsmpls += declen;
882    totalbits += 8 * stream_len;
883#ifdef _DEBUG
884    kbps = ((double)sampFreqKHz * 1000.) / ((double)cur_framesmpls) * 8.0 *
885           stream_len / 1000.0;  // kbits/s
886    fy = fopen("bit_rate.dat", "a");
887    fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
888    fclose(fy);
889
890#endif /* _DEBUG */
891  }
892  printf("\n");
893  printf("total bits               = %d bits\n", totalbits);
894  printf("measured average bitrate = %0.3f kbits/s\n",
895         (double)totalbits * (sampFreqKHz) / totalsmpls);
896  if (doTransCoding) {
897    printf("Transcoding average bit-rate = %0.3f kbps\n",
898           (double)numTransCodingBytes * 8.0 * (sampFreqKHz) / totalsmpls);
899    fclose(transCodingFile);
900  }
901  printf("\n");
902
903  /* Runtime statistics */
904  runtime = (double)(clock() / (double)CLOCKS_PER_SEC - starttime);
905  length_file = length_file / (sampFreqKHz * 1000.);
906
907  printf("\n\nLength of speech file: %.1f s\n", length_file);
908  printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n", runtime,
909         (100 * runtime / length_file));
910
911  if (maxStreamLen30 != 0) {
912    printf("Maximum payload size 30ms Frames %d bytes (%0.3f kbps)\n",
913           maxStreamLen30, maxStreamLen30 * 8 / 30.);
914  }
915  if (maxStreamLen60 != 0) {
916    printf("Maximum payload size 60ms Frames %d bytes (%0.3f kbps)\n",
917           maxStreamLen60, maxStreamLen60 * 8 / 60.);
918  }
919  // fprintf(stderr, "\n");
920
921  fprintf(stderr, "   %.1f s", length_file);
922  fprintf(stderr, "   %0.1f kbps",
923          (double)totalbits * (sampFreqKHz) / totalsmpls);
924  if (maxStreamLen30 != 0) {
925    fprintf(stderr, "   plmax-30ms %d bytes (%0.0f kbps)", maxStreamLen30,
926            maxStreamLen30 * 8 / 30.);
927  }
928  if (maxStreamLen60 != 0) {
929    fprintf(stderr, "   plmax-60ms %d bytes (%0.0f kbps)", maxStreamLen60,
930            maxStreamLen60 * 8 / 60.);
931  }
932  if (doTransCoding) {
933    fprintf(stderr, "  transcoding rate %.0f kbps",
934            (double)numTransCodingBytes * 8.0 * (sampFreqKHz) / totalsmpls);
935  }
936
937  fclose(inp);
938  fclose(outp);
939  WebRtcIsac_Free(ISAC_main_inst);
940
941  exit(0);
942}
943