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