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