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