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 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <time.h>
15 #include <ctype.h>
16
17 #include "webrtc/modules/audio_coding/codecs/isac/fix/include/isacfix.h"
18 #include "webrtc/test/testsupport/perf_test.h"
19
20 // TODO(kma): Clean up the code and change benchmarking the whole codec to
21 // separate encoder and decoder.
22
23 /* Defines */
24 #define SEED_FILE "randseed.txt" /* Used when running decoder on garbage data */
25 #define MAX_FRAMESAMPLES 960 /* max number of samples per frame (= 60 ms frame) */
26 #define FRAMESAMPLES_10ms 160 /* number of samples per 10ms frame */
27 #define FS 16000 /* sampling frequency (Hz) */
28
29 /* Function for reading audio data from PCM file */
readframe(int16_t * data,FILE * inp,int length)30 int readframe(int16_t *data, FILE *inp, int length) {
31
32 short k, rlen, status = 0;
33
34 rlen = fread(data, sizeof(int16_t), length, inp);
35 if (rlen < length) {
36 for (k = rlen; k < length; k++)
37 data[k] = 0;
38 status = 1;
39 }
40
41 return status;
42 }
43
44 /* Struct for bottleneck model */
45 typedef struct {
46 uint32_t send_time; /* samples */
47 uint32_t arrival_time; /* samples */
48 uint32_t sample_count; /* samples */
49 uint16_t rtp_number;
50 } BottleNeckModel;
51
get_arrival_time(int current_framesamples,size_t packet_size,int bottleneck,BottleNeckModel * BN_data)52 void get_arrival_time(int current_framesamples, /* samples */
53 size_t packet_size, /* bytes */
54 int bottleneck, /* excluding headers; bits/s */
55 BottleNeckModel *BN_data)
56 {
57 const int HeaderSize = 35;
58 int HeaderRate;
59
60 HeaderRate = HeaderSize * 8 * FS / current_framesamples; /* bits/s */
61
62 /* everything in samples */
63 BN_data->sample_count = BN_data->sample_count + current_framesamples;
64
65 BN_data->arrival_time += static_cast<uint32_t>(
66 ((packet_size + HeaderSize) * 8 * FS) / (bottleneck + HeaderRate));
67 BN_data->send_time += current_framesamples;
68
69 if (BN_data->arrival_time < BN_data->sample_count)
70 BN_data->arrival_time = BN_data->sample_count;
71
72 BN_data->rtp_number++;
73 }
74
get_arrival_time2(int current_framesamples,int current_delay,BottleNeckModel * BN_data)75 void get_arrival_time2(int current_framesamples,
76 int current_delay,
77 BottleNeckModel *BN_data)
78 {
79 if (current_delay == -1)
80 //dropped packet
81 {
82 BN_data->arrival_time += current_framesamples;
83 }
84 else if (current_delay != -2)
85 {
86 //
87 BN_data->arrival_time += (current_framesamples + ((FS/1000) * current_delay));
88 }
89 //else
90 //current packet has same timestamp as previous packet
91
92 BN_data->rtp_number++;
93 }
94
main(int argc,char * argv[])95 int main(int argc, char* argv[])
96 {
97
98 char inname[100], outname[100], outbitsname[100], bottleneck_file[100];
99 FILE *inp, *outp, *f_bn, *outbits;
100 int endfile;
101
102 size_t i;
103 int errtype, h = 0, k, packetLossPercent = 0;
104 int16_t CodingMode;
105 int16_t bottleneck;
106 int framesize = 30; /* ms */
107 int cur_framesmpls, err = 0, lostPackets = 0;
108
109 /* Runtime statistics */
110 double starttime, runtime, length_file;
111
112 int stream_len_int = 0;
113 size_t stream_len = 0;
114 int16_t framecnt;
115 int declen = 0;
116 int16_t shortdata[FRAMESAMPLES_10ms];
117 int16_t decoded[MAX_FRAMESAMPLES];
118 uint16_t streamdata[500];
119 int16_t speechType[1];
120 size_t prevFrameSize = 1;
121 int16_t rateBPS = 0;
122 int16_t fixedFL = 0;
123 int16_t payloadSize = 0;
124 int32_t payloadRate = 0;
125 int setControlBWE = 0;
126 int readLoss;
127 FILE *plFile = NULL;
128
129 char version_number[20];
130 char tmpBit[5] = ".bit";
131
132 int totalbits =0;
133 int totalsmpls =0;
134 int16_t testNum, testCE;
135
136 FILE *fp_gns = NULL;
137 int gns = 0;
138 int cur_delay = 0;
139 char gns_file[100];
140
141 int nbTest = 0;
142 int16_t lostFrame;
143 float scale = (float)0.7;
144 /* only one structure used for ISAC encoder */
145 ISACFIX_MainStruct *ISAC_main_inst = NULL;
146
147 /* For fault test 10, garbage data */
148 FILE *seedfile;
149 unsigned int random_seed = (unsigned int) time(NULL);//1196764538
150
151 BottleNeckModel BN_data;
152 f_bn = NULL;
153
154 readLoss = 0;
155 packetLossPercent = 0;
156
157 /* Handling wrong input arguments in the command line */
158 if ((argc<3) || (argc>21)) {
159 printf("\n\nWrong number of arguments or flag values.\n\n");
160
161 printf("\n");
162 WebRtcIsacfix_version(version_number);
163 printf("iSAC version %s \n\n", version_number);
164
165 printf("Usage:\n\n");
166 printf("./kenny.exe [-F num][-I] bottleneck_value infile outfile \n\n");
167 printf("with:\n");
168 printf("[-I] :if -I option is specified, the coder will use\n");
169 printf(" an instantaneous Bottleneck value. If not, it\n");
170 printf(" will be an adaptive Bottleneck value.\n\n");
171 printf("bottleneck_value :the value of the bottleneck provided either\n");
172 printf(" as a fixed value (e.g. 25000) or\n");
173 printf(" read from a file (e.g. bottleneck.txt)\n\n");
174 printf("[-INITRATE num] :Set a new value for initial rate. Note! Only used"
175 " in adaptive mode.\n\n");
176 printf("[-FL num] :Set (initial) frame length in msec. Valid length"
177 " are 30 and 60 msec.\n\n");
178 printf("[-FIXED_FL] :Frame length to be fixed to initial value.\n\n");
179 printf("[-MAX num] :Set the limit for the payload size of iSAC"
180 " in bytes. \n");
181 printf(" Minimum 100, maximum 400.\n\n");
182 printf("[-MAXRATE num] :Set the maxrate for iSAC in bits per second. \n");
183 printf(" Minimum 32000, maximum 53400.\n\n");
184 printf("[-F num] :if -F option is specified, the test function\n");
185 printf(" will run the iSAC API fault scenario specified"
186 " by the\n");
187 printf(" supplied number.\n");
188 printf(" F 1 - Call encoder prior to init encoder call\n");
189 printf(" F 2 - Call decoder prior to init decoder call\n");
190 printf(" F 3 - Call decoder prior to encoder call\n");
191 printf(" F 4 - Call decoder with a too short coded"
192 " sequence\n");
193 printf(" F 5 - Call decoder with a too long coded"
194 " sequence\n");
195 printf(" F 6 - Call decoder with random bit stream\n");
196 printf(" F 7 - Call init encoder/decoder at random"
197 " during a call\n");
198 printf(" F 8 - Call encoder/decoder without having"
199 " allocated memory for \n");
200 printf(" encoder/decoder instance\n");
201 printf(" F 9 - Call decodeB without calling decodeA\n");
202 printf(" F 10 - Call decodeB with garbage data\n");
203 printf("[-PL num] : if -PL option is specified 0<num<100 will "
204 "specify the\n");
205 printf(" percentage of packet loss\n\n");
206 printf("[-G file] : if -G option is specified the file given is"
207 " a .gns file\n");
208 printf(" that represents a network profile\n\n");
209 printf("[-NB num] : if -NB option, use the narrowband interfaces\n");
210 printf(" num=1 => encode with narrowband encoder"
211 " (infile is narrowband)\n");
212 printf(" num=2 => decode with narrowband decoder"
213 " (outfile is narrowband)\n\n");
214 printf("[-CE num] : Test of APIs used by Conference Engine.\n");
215 printf(" CE 1 - createInternal, freeInternal,"
216 " getNewBitstream \n");
217 printf(" CE 2 - transcode, getBWE \n");
218 printf(" CE 3 - getSendBWE, setSendBWE. \n\n");
219 printf("[-RTP_INIT num] : if -RTP_INIT option is specified num will be"
220 " the initial\n");
221 printf(" value of the rtp sequence number.\n\n");
222 printf("infile : Normal speech input file\n\n");
223 printf("outfile : Speech output file\n\n");
224 printf("Example usage : \n\n");
225 printf("./kenny.exe -I bottleneck.txt speechIn.pcm speechOut.pcm\n\n");
226 exit(0);
227
228 }
229
230 /* Print version number */
231 WebRtcIsacfix_version(version_number);
232 printf("iSAC version %s \n\n", version_number);
233
234 /* Loop over all command line arguments */
235 CodingMode = 0;
236 testNum = 0;
237 testCE = 0;
238 for (i = 1; i + 2 < static_cast<size_t>(argc); i++) {
239 /* Instantaneous mode */
240 if (!strcmp ("-I", argv[i])) {
241 printf("\nInstantaneous BottleNeck\n");
242 CodingMode = 1;
243 i++;
244 }
245
246 /* Set (initial) bottleneck value */
247 if (!strcmp ("-INITRATE", argv[i])) {
248 rateBPS = atoi(argv[i + 1]);
249 setControlBWE = 1;
250 if ((rateBPS < 10000) || (rateBPS > 32000)) {
251 printf("\n%d is not a initial rate. "
252 "Valid values are in the range 10000 to 32000.\n", rateBPS);
253 exit(0);
254 }
255 printf("\nNew initial rate: %d\n", rateBPS);
256 i++;
257 }
258
259 /* Set (initial) framelength */
260 if (!strcmp ("-FL", argv[i])) {
261 framesize = atoi(argv[i + 1]);
262 if ((framesize != 30) && (framesize != 60)) {
263 printf("\n%d is not a valid frame length. "
264 "Valid length are 30 and 60 msec.\n", framesize);
265 exit(0);
266 }
267 printf("\nFrame Length: %d\n", framesize);
268 i++;
269 }
270
271 /* Fixed frame length */
272 if (!strcmp ("-FIXED_FL", argv[i])) {
273 fixedFL = 1;
274 setControlBWE = 1;
275 }
276
277 /* Set maximum allowed payload size in bytes */
278 if (!strcmp ("-MAX", argv[i])) {
279 payloadSize = atoi(argv[i + 1]);
280 printf("Maximum Payload Size: %d\n", payloadSize);
281 i++;
282 }
283
284 /* Set maximum rate in bytes */
285 if (!strcmp ("-MAXRATE", argv[i])) {
286 payloadRate = atoi(argv[i + 1]);
287 printf("Maximum Rate in kbps: %d\n", payloadRate);
288 i++;
289 }
290
291 /* Test of fault scenarious */
292 if (!strcmp ("-F", argv[i])) {
293 testNum = atoi(argv[i + 1]);
294 printf("\nFault test: %d\n", testNum);
295 if (testNum < 1 || testNum > 10) {
296 printf("\n%d is not a valid Fault Scenario number."
297 " Valid Fault Scenarios are numbered 1-10.\n", testNum);
298 exit(0);
299 }
300 i++;
301 }
302
303 /* Packet loss test */
304 if (!strcmp ("-PL", argv[i])) {
305 if( isdigit( *argv[i+1] ) ) {
306 packetLossPercent = atoi( argv[i+1] );
307 if( (packetLossPercent < 0) | (packetLossPercent > 100) ) {
308 printf( "\nInvalid packet loss perentage \n" );
309 exit( 0 );
310 }
311 if( packetLossPercent > 0 ) {
312 printf( "\nSimulating %d %% of independent packet loss\n",
313 packetLossPercent );
314 } else {
315 printf( "\nNo Packet Loss Is Simulated \n" );
316 }
317 readLoss = 0;
318 } else {
319 readLoss = 1;
320 plFile = fopen( argv[i+1], "rb" );
321 if( plFile == NULL ) {
322 printf( "\n couldn't open the frameloss file: %s\n", argv[i+1] );
323 exit( 0 );
324 }
325 printf( "\nSimulating packet loss through the given "
326 "channel file: %s\n", argv[i+1] );
327 }
328 i++;
329 }
330
331 /* Random packetlosses */
332 if (!strcmp ("-rnd", argv[i])) {
333 srand(time(NULL) );
334 printf( "\n Random pattern in lossed packets \n" );
335 }
336
337 /* Use gns file */
338 if (!strcmp ("-G", argv[i])) {
339 sscanf(argv[i + 1], "%s", gns_file);
340 fp_gns = fopen(gns_file, "rb");
341 if (fp_gns == NULL) {
342 printf("Cannot read file %s.\n", gns_file);
343 exit(0);
344 }
345 gns = 1;
346 i++;
347 }
348
349 /* Run Narrowband interfaces (either encoder or decoder) */
350 if (!strcmp ("-NB", argv[i])) {
351 nbTest = atoi(argv[i + 1]);
352 i++;
353 }
354
355 /* Run Conference Engine APIs */
356 if (!strcmp ("-CE", argv[i])) {
357 testCE = atoi(argv[i + 1]);
358 if (testCE==1 || testCE==2) {
359 i++;
360 scale = (float)atof( argv[i+1] );
361 } else if (testCE < 1 || testCE > 3) {
362 printf("\n%d is not a valid CE-test number, valid Fault "
363 "Scenarios are numbered 1-3\n", testCE);
364 exit(0);
365 }
366 i++;
367 }
368
369 /* Set initial RTP number */
370 if (!strcmp ("-RTP_INIT", argv[i])) {
371 i++;
372 }
373 }
374
375 /* Get Bottleneck value */
376 /* Gns files and bottleneck should not and can not be used simultaneously */
377 bottleneck = atoi(argv[CodingMode+1]);
378 if (bottleneck == 0 && gns == 0) {
379 sscanf(argv[CodingMode+1], "%s", bottleneck_file);
380 f_bn = fopen(bottleneck_file, "rb");
381 if (f_bn == NULL) {
382 printf("No value provided for BottleNeck and cannot read file %s\n",
383 bottleneck_file);
384 exit(0);
385 } else {
386 int aux_var;
387 printf("reading bottleneck rates from file %s\n\n",bottleneck_file);
388 if (fscanf(f_bn, "%d", &aux_var) == EOF) {
389 /* Set pointer to beginning of file */
390 fseek(f_bn, 0L, SEEK_SET);
391 if (fscanf(f_bn, "%d", &aux_var) == EOF) {
392 exit(0);
393 }
394 }
395 bottleneck = (int16_t)aux_var;
396 /* Bottleneck is a cosine function
397 * Matlab code for writing the bottleneck file:
398 * BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
399 * fid = fopen('bottleneck.txt', 'wb');
400 * fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
401 */
402 }
403 } else {
404 f_bn = NULL;
405 printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
406 }
407
408 if (CodingMode == 0) {
409 printf("\nAdaptive BottleNeck\n");
410 }
411
412 /* Get Input and Output files */
413 sscanf(argv[argc-2], "%s", inname);
414 sscanf(argv[argc-1], "%s", outname);
415
416 /* Add '.bit' to output bitstream file */
417 while ((int)outname[h] != 0) {
418 outbitsname[h] = outname[h];
419 h++;
420 }
421 for (k=0; k<5; k++) {
422 outbitsname[h] = tmpBit[k];
423 h++;
424 }
425 if ((inp = fopen(inname,"rb")) == NULL) {
426 printf(" iSAC: Cannot read file %s\n", inname);
427 exit(1);
428 }
429 if ((outp = fopen(outname,"wb")) == NULL) {
430 printf(" iSAC: Cannot write file %s\n", outname);
431 exit(1);
432 }
433
434 if ((outbits = fopen(outbitsname,"wb")) == NULL) {
435 printf(" iSAC: Cannot write file %s\n", outbitsname);
436 exit(1);
437 }
438 printf("\nInput:%s\nOutput:%s\n\n", inname, outname);
439
440 /* Error test number 10, garbage data */
441 if (testNum == 10) {
442 /* Test to run decoder with garbage data */
443 srand(random_seed);
444
445 if ( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL ) {
446 printf("Error: Could not open file %s\n", SEED_FILE);
447 }
448 else {
449 fprintf(seedfile, "%u\n", random_seed);
450 fclose(seedfile);
451 }
452 }
453
454 /* Runtime statistics */
455 starttime = clock()/(double)CLOCKS_PER_SEC;
456
457 /* Initialize the ISAC and BN structs */
458 if (testNum != 8)
459 {
460 if(1){
461 err =WebRtcIsacfix_Create(&ISAC_main_inst);
462 }else{
463 /* Test the Assign functions */
464 int sss;
465 void *ppp;
466 err =WebRtcIsacfix_AssignSize(&sss);
467 ppp=malloc(sss);
468 err =WebRtcIsacfix_Assign(&ISAC_main_inst,ppp);
469 }
470 /* Error check */
471 if (err < 0) {
472 printf("\n\n Error in create.\n\n");
473 }
474 if (testCE == 1) {
475 err = WebRtcIsacfix_CreateInternal(ISAC_main_inst);
476 /* Error check */
477 if (err < 0) {
478 printf("\n\n Error in createInternal.\n\n");
479 }
480 }
481 }
482
483 /* Init of bandwidth data */
484 BN_data.send_time = 0;
485 BN_data.arrival_time = 0;
486 BN_data.sample_count = 0;
487 BN_data.rtp_number = 0;
488
489 /* Initialize encoder and decoder */
490 framecnt= 0;
491 endfile = 0;
492 if (testNum != 1) {
493 WebRtcIsacfix_EncoderInit(ISAC_main_inst, CodingMode);
494 }
495 if (testNum != 2) {
496 WebRtcIsacfix_DecoderInit(ISAC_main_inst);
497 }
498
499 if (CodingMode == 1) {
500 err = WebRtcIsacfix_Control(ISAC_main_inst, bottleneck, framesize);
501 if (err < 0) {
502 /* exit if returned with error */
503 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
504 printf("\n\n Error in control: %d.\n\n", errtype);
505 }
506 } else if(setControlBWE == 1) {
507 err = WebRtcIsacfix_ControlBwe(ISAC_main_inst, rateBPS, framesize, fixedFL);
508 }
509
510 if (payloadSize != 0) {
511 err = WebRtcIsacfix_SetMaxPayloadSize(ISAC_main_inst, payloadSize);
512 if (err < 0) {
513 /* exit if returned with error */
514 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
515 printf("\n\n Error in SetMaxPayloadSize: %d.\n\n", errtype);
516 exit(EXIT_FAILURE);
517 }
518 }
519 if (payloadRate != 0) {
520 err = WebRtcIsacfix_SetMaxRate(ISAC_main_inst, payloadRate);
521 if (err < 0) {
522 /* exit if returned with error */
523 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
524 printf("\n\n Error in SetMaxRateInBytes: %d.\n\n", errtype);
525 exit(EXIT_FAILURE);
526 }
527 }
528
529 *speechType = 1;
530
531
532 while (endfile == 0) {
533
534 if(testNum == 7 && (rand()%2 == 0)) {
535 err = WebRtcIsacfix_EncoderInit(ISAC_main_inst, CodingMode);
536 /* Error check */
537 if (err < 0) {
538 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
539 printf("\n\n Error in encoderinit: %d.\n\n", errtype);
540 }
541
542 WebRtcIsacfix_DecoderInit(ISAC_main_inst);
543 }
544
545
546 cur_framesmpls = 0;
547 while (1) {
548 /* Read 10 ms speech block */
549 if (nbTest != 1) {
550 endfile = readframe(shortdata, inp, FRAMESAMPLES_10ms);
551 } else {
552 endfile = readframe(shortdata, inp, (FRAMESAMPLES_10ms/2));
553 }
554
555 if (testNum == 7) {
556 srand(time(NULL));
557 }
558
559 /* iSAC encoding */
560 if (!(testNum == 3 && framecnt == 0)) {
561 if (nbTest != 1) {
562 short bwe;
563
564 /* Encode */
565 stream_len_int = WebRtcIsacfix_Encode(ISAC_main_inst,
566 shortdata,
567 (uint8_t*)streamdata);
568
569 /* If packet is ready, and CE testing, call the different API
570 functions from the internal API. */
571 if (stream_len_int>0) {
572 if (testCE == 1) {
573 err = WebRtcIsacfix_ReadBwIndex(
574 reinterpret_cast<const uint8_t*>(streamdata),
575 static_cast<size_t>(stream_len_int),
576 &bwe);
577 stream_len_int = WebRtcIsacfix_GetNewBitStream(
578 ISAC_main_inst,
579 bwe,
580 scale,
581 reinterpret_cast<uint8_t*>(streamdata));
582 } else if (testCE == 2) {
583 /* transcode function not supported */
584 } else if (testCE == 3) {
585 /* Only for Function testing. The functions should normally
586 not be used in this way */
587
588 err = WebRtcIsacfix_GetDownLinkBwIndex(ISAC_main_inst, &bwe);
589 /* Error Check */
590 if (err < 0) {
591 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
592 printf("\nError in getSendBWE: %d.\n", errtype);
593 }
594
595 err = WebRtcIsacfix_UpdateUplinkBw(ISAC_main_inst, bwe);
596 /* Error Check */
597 if (err < 0) {
598 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
599 printf("\nError in setBWE: %d.\n", errtype);
600 }
601
602 }
603 }
604 } else {
605 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
606 stream_len_int = WebRtcIsacfix_EncodeNb(ISAC_main_inst,
607 shortdata,
608 streamdata);
609 #else
610 stream_len_int = -1;
611 #endif
612 }
613 }
614 else
615 {
616 break;
617 }
618
619 if (stream_len_int < 0 || err < 0) {
620 /* exit if returned with error */
621 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
622 printf("\nError in encoder: %d.\n", errtype);
623 } else {
624 stream_len = static_cast<size_t>(stream_len_int);
625 if (fwrite(streamdata, sizeof(char), stream_len, outbits) !=
626 stream_len) {
627 return -1;
628 }
629 }
630
631 cur_framesmpls += FRAMESAMPLES_10ms;
632
633 /* read next bottleneck rate */
634 if (f_bn != NULL) {
635 int aux_var;
636 if (fscanf(f_bn, "%d", &aux_var) == EOF) {
637 /* Set pointer to beginning of file */
638 fseek(f_bn, 0L, SEEK_SET);
639 if (fscanf(f_bn, "%d", &aux_var) == EOF) {
640 exit(0);
641 }
642 }
643 bottleneck = (int16_t)aux_var;
644 if (CodingMode == 1) {
645 WebRtcIsacfix_Control(ISAC_main_inst, bottleneck, framesize);
646 }
647 }
648
649 /* exit encoder loop if the encoder returned a bitstream */
650 if (stream_len != 0) break;
651 }
652
653 /* make coded sequence to short be inreasing */
654 /* the length the decoder expects */
655 if (testNum == 4) {
656 stream_len += 10;
657 }
658
659 /* make coded sequence to long be decreasing */
660 /* the length the decoder expects */
661 if (testNum == 5) {
662 stream_len -= 10;
663 }
664
665 if (testNum == 6) {
666 srand(time(NULL));
667 for (i = 0; i < stream_len; i++ ) {
668 streamdata[i] = rand();
669 }
670 }
671
672 /* set pointer to beginning of file */
673 if (fp_gns != NULL) {
674 if (fscanf(fp_gns, "%d", &cur_delay) == EOF) {
675 fseek(fp_gns, 0L, SEEK_SET);
676 if (fscanf(fp_gns, "%d", &cur_delay) == EOF) {
677 exit(0);
678 }
679 }
680 }
681
682 /* simulate packet handling through NetEq and the modem */
683 if (!(testNum == 3 && framecnt == 0)) {
684 if (gns == 0) {
685 get_arrival_time(cur_framesmpls, stream_len, bottleneck,
686 &BN_data);
687 } else {
688 get_arrival_time2(cur_framesmpls, cur_delay, &BN_data);
689 }
690 }
691
692 /* packet not dropped */
693 if (cur_delay != -1) {
694
695 /* Error test number 10, garbage data */
696 if (testNum == 10) {
697 for ( i = 0; i < stream_len; i++) {
698 streamdata[i] = (short) (streamdata[i] + (short) rand());
699 }
700 }
701
702 if (testNum != 9) {
703 err = WebRtcIsacfix_UpdateBwEstimate(
704 ISAC_main_inst,
705 reinterpret_cast<const uint8_t*>(streamdata),
706 stream_len,
707 BN_data.rtp_number,
708 BN_data.send_time,
709 BN_data.arrival_time);
710
711 if (err < 0) {
712 /* exit if returned with error */
713 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
714 printf("\nError in decoder: %d.\n", errtype);
715 }
716 }
717
718 if( readLoss == 1 ) {
719 if( fread( &lostFrame, sizeof(int16_t), 1, plFile ) != 1 ) {
720 rewind( plFile );
721 }
722 lostFrame = !lostFrame;
723 } else {
724 lostFrame = (rand()%100 < packetLossPercent);
725 }
726
727
728
729 /* iSAC decoding */
730 if( lostFrame && framecnt > 0) {
731 if (nbTest !=2) {
732 declen = static_cast<int>(
733 WebRtcIsacfix_DecodePlc(ISAC_main_inst, decoded, prevFrameSize));
734 } else {
735 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
736 declen = static_cast<int>(WebRtcIsacfix_DecodePlcNb(
737 ISAC_main_inst, decoded, prevFrameSize));
738 #else
739 declen = -1;
740 #endif
741 }
742 lostPackets++;
743 } else {
744 if (nbTest !=2 ) {
745 size_t FL;
746 /* Call getFramelen, only used here for function test */
747 err = WebRtcIsacfix_ReadFrameLen(
748 reinterpret_cast<const uint8_t*>(streamdata), stream_len, &FL);
749 declen = WebRtcIsacfix_Decode(
750 ISAC_main_inst,
751 reinterpret_cast<const uint8_t*>(streamdata),
752 stream_len,
753 decoded,
754 speechType);
755 /* Error check */
756 if (err < 0 || declen < 0 || FL != static_cast<size_t>(declen)) {
757 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
758 printf("\nError in decode_B/or getFrameLen: %d.\n", errtype);
759 }
760 prevFrameSize = static_cast<size_t>(declen/480);
761
762 } else {
763 #ifdef WEBRTC_ISAC_FIX_NB_CALLS_ENABLED
764 declen = WebRtcIsacfix_DecodeNb( ISAC_main_inst, streamdata,
765 stream_len, decoded, speechType );
766 #else
767 declen = -1;
768 #endif
769 prevFrameSize = static_cast<size_t>(declen / 240);
770 }
771 }
772
773 if (declen <= 0) {
774 /* exit if returned with error */
775 errtype=WebRtcIsacfix_GetErrorCode(ISAC_main_inst);
776 printf("\nError in decoder: %d.\n", errtype);
777 }
778
779 /* Write decoded speech frame to file */
780 if (fwrite(decoded, sizeof(int16_t),
781 declen, outp) != (size_t)declen) {
782 return -1;
783 }
784 // fprintf( ratefile, "%f \n", stream_len / ( ((double)declen)/
785 // ((double)FS) ) * 8 );
786 } else {
787 lostPackets++;
788 }
789 framecnt++;
790
791 totalsmpls += declen;
792 totalbits += static_cast<int>(8 * stream_len);
793
794 /* Error test number 10, garbage data */
795 if (testNum == 10) {
796 if ( (seedfile = fopen(SEED_FILE, "a+t") ) == NULL ) {
797 printf( "Error: Could not open file %s\n", SEED_FILE);
798 }
799 else {
800 fprintf(seedfile, "ok\n\n");
801 fclose(seedfile);
802 }
803 }
804 }
805 printf("\nLost Frames %d ~ %4.1f%%\n", lostPackets,
806 (double)lostPackets/(double)framecnt*100.0 );
807 printf("\n\ntotal bits = %d bits", totalbits);
808 printf("\nmeasured average bitrate = %0.3f kbits/s",
809 (double)totalbits *(FS/1000) / totalsmpls);
810 printf("\n");
811
812 /* Runtime statistics */
813
814
815 runtime = (double)(((double)clock()/(double)CLOCKS_PER_SEC)-starttime);
816 length_file = ((double)framecnt*(double)declen/FS);
817 printf("\n\nLength of speech file: %.1f s\n", length_file);
818 printf("Time to run iSAC: %.2f s (%.2f %% of realtime)\n\n",
819 runtime, (100*runtime/length_file));
820 printf("\n\n_______________________________________________\n");
821
822 #if 0
823 // TODO: use PrintResult in webrtc/test/testsupport/perf_test.cc?
824 // Record the results with Perf test tools.
825 webrtc::test::PrintResult("isac", "", "time_per_10ms_frame",
826 (runtime * 10000) / length_file, "us", false);
827 #endif
828
829 fclose(inp);
830 fclose(outp);
831 fclose(outbits);
832
833 if ( testCE == 1) {
834 WebRtcIsacfix_FreeInternal(ISAC_main_inst);
835 }
836 WebRtcIsacfix_Free(ISAC_main_inst);
837 return 0;
838 }
839