Beispiel #1
0
/*
#ifdef __cplusplus
extern "C" {
#endif
*/
int main(int argc, char* argv[]){ 

	/* Parameters */
	FILE *pInFile, *pOutFile, *pChcFile; 
	WebRtc_Word8 inFile[40];
	WebRtc_Word8 outFile[40];
	WebRtc_Word8 chcFile[40];
	WebRtc_Word8 codec[10];
	WebRtc_Word16 bitrt, spType, size;
	WebRtc_UWord16 frameLen;
	WebRtc_Word16 sigOut[1000], sigIn[1000]; 
	WebRtc_UWord16 bitStream[500]; /* double to 32 kbps for 60 ms */

	WebRtc_Word16 chc, ok;
	int noOfCalls, cdlen;
	WebRtc_Word16 noOfLostFrames;
	int err, errtype;

	BottleNeckModel       BN_data;

	int totalbits =0;
	int totalsmpls =0;

	/*End Parameters*/

	
	if ((argc==6)||(argc==7) ){

		strcpy(codec,argv[5]);

		if(argc==7){
			if (!_stricmp("isac",codec)){
				bitrt = atoi(argv[6]);
				if ( (bitrt<10000)&&(bitrt>32000)){
					printf("Error: Supported bit rate in the range 10000-32000 bps!\n");
					exit(-1);
				}

			}else{
	      printf("Error: Codec not recognized. Check spelling!\n");
	      exit(-1);
			}

		} else { 
				printf("Error: Codec not recognized. Check spelling!\n");
				exit(-1);
		}
	} else {
		printf("Error: Wrong number of input parameter!\n\n");
		exit(-1);
	}
	
	frameLen = atoi(argv[4]);
	strcpy(chcFile,argv[3]);
	strcpy(outFile,argv[2]);
	strcpy(inFile,argv[1]);

	/*  Open file streams */
	if( (pInFile = fopen(inFile,"rb")) == NULL ) {
		printf( "Error: Did not find input file!\n" );
		exit(-1);
	}
	strcat(outFile,"_");
	strcat(outFile, argv[4]);
	strcat(outFile,"_");
	strcat(outFile, codec);
	
	if (argc==7){
		strcat(outFile,"_");
		strcat(outFile, argv[6]);
	}
	if (_stricmp("none", chcFile)){
		strcat(outFile,"_");
		strcat(outFile, "plc");
	}
	
	strcat(outFile, ".otp");
	
	if (_stricmp("none", chcFile)){
		if( (pChcFile = fopen(chcFile,"rb")) == NULL ) {
			printf( "Error: Did not find channel file!\n" );
			exit(-1);
		}
	}
    /******************************************************************/
	if (!_stricmp("isac", codec)){    /*    ISAC   */
		if ((frameLen!=480)&&(frameLen!=960)) {
			printf("Error: ISAC only supports 480 and 960 samples per frame (not %d)\n", frameLen);
			exit(-1);
		}
		if( (pOutFile = fopen(outFile,"wb")) == NULL ) {
			printf( "Could not open output file!\n" );
			exit(-1);
		}
		ok=WebRtcIsacfix_Create(&ISACfix_inst);
		if (ok!=0) {
			printf("Couldn't allocate memory for iSAC fix instance\n");
			exit(-1);
		}

		BN_data.arrival_time  = 0;
		BN_data.sample_count  = 0;
		BN_data.rtp_number    = 0;

		WebRtcIsacfix_EncoderInit(ISACfix_inst,1);
		WebRtcIsacfix_DecoderInit(ISACfix_inst);
		err = WebRtcIsacfix_Control(ISACfix_inst, bitrt, (frameLen>>4));
		if (err < 0) {
				/* exit if returned with error */
				errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
				printf("\n\n Error in initialization: %d.\n\n", errtype);
				exit(EXIT_FAILURE);
			}
		/* loop over frame */
		while (fread(sigIn,sizeof(WebRtc_Word16),frameLen,pInFile) == frameLen) {
			
			noOfCalls=0;
			cdlen=0;
			while (cdlen<=0) {
				cdlen=WebRtcIsacfix_Encode(ISACfix_inst,&sigIn[noOfCalls*160],(WebRtc_Word16*)bitStream);
				if(cdlen==-1){
					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
					printf("\n\nError in encoder: %d.\n\n", errtype);
					exit(-1);
				}
				noOfCalls++;
			}
	
	
			if(_stricmp("none", chcFile)){
				if (fread(&chc,sizeof(WebRtc_Word16),1,pChcFile)!=1) /* packet may be lost */
					break;
			} else {
				chc = 1; /* packets never lost */
			}
					
			/* simulate packet handling through NetEq and the modem */
			get_arrival_time(frameLen, cdlen, bitrt, &BN_data);
			
			if (chc){ /* decode */

				err = WebRtcIsacfix_UpdateBwEstimate1(ISACfix_inst,
								  bitStream,
								  cdlen,
								  BN_data.rtp_number,
								  BN_data.arrival_time);

				if (err < 0) {
					/* exit if returned with error */
					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
					printf("\n\nError in decoder: %d.\n\n", errtype);
					exit(EXIT_FAILURE);
				}
				size = WebRtcIsacfix_Decode(ISACfix_inst, bitStream, cdlen, sigOut, &spType);
				if(size<=0){
					/* exit if returned with error */
					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
					printf("\n\nError in decoder: %d.\n\n", errtype);
					exit(-1);
				}
			} else { /* PLC */
				if (frameLen == 480){
					noOfLostFrames = 1;
				} else{
					noOfLostFrames = 2;
				}
				size = WebRtcIsacfix_DecodePlc(ISACfix_inst, sigOut, noOfLostFrames );
				if(size<=0){
					errtype=WebRtcIsacfix_GetErrorCode(ISACfix_inst);
					printf("\n\nError in decoder: %d.\n\n", errtype);
					exit(-1);
				}
			}
				
			/* Write decoded speech to file */
			fwrite(sigOut,sizeof(short),size,pOutFile);

		totalbits += 8 * cdlen;
		totalsmpls += size;

		}
	/******************************************************************/
	}

//	printf("\n\ntotal bits				= %d bits", totalbits);
	printf("\nmeasured average bitrate		= %0.3f kbits/s", (double)totalbits * 16 / totalsmpls);
	printf("\n");


	fclose(pInFile);
	fclose(pOutFile);
	if (_stricmp("none", chcFile)){
		fclose(pChcFile);
	}

	if (!_stricmp("isac", codec)){
		WebRtcIsacfix_Free(ISACfix_inst);
	}
									 			
	return 0;

}
int main(int argc, char* argv[]) {
    char inname[50], outname[50], bottleneck_file[50], bitfilename[60],
         bitending[10] = "_bits.pcm";
    FILE* inp, *outp, *f_bn, *bitsp;
    int framecnt, endfile;

    int i, j, errtype, plc = 0;
    int16_t CodingMode;
    int16_t bottleneck;

    int framesize = 30; /* ms */
    // int framesize = 60; /* To invoke cisco complexity case at frame 2252 */

    int cur_framesmpls, err;

    /* Runtime statistics */
    double starttime;
    double runtime;
    double length_file;

    size_t stream_len = 0;
    int declen;

    int16_t shortdata[FRAMESAMPLES_10ms];
    int16_t decoded[MAX_FRAMESAMPLES];
    uint16_t streamdata[600];
    int16_t speechType[1];

    // int16_t* iSACstruct;

    char version_number[20];
    int mode = -1, tmp, nbTest = 0; /*,sss;*/

#if !defined(NDEBUG)
    FILE* fy;
    double kbps;
    size_t totalbits = 0;
    int totalsmpls = 0;
#endif

    /* only one structure used for ISAC encoder */
    ISAC_MainStruct* ISAC_main_inst;
    ISACFIX_MainStruct* ISACFIX_main_inst;

    BottleNeckModel BN_data;
    f_bn = NULL;

#if !defined(NDEBUG)
    fy = fopen("bit_rate.dat", "w");
    fclose(fy);
    fy = fopen("bytes_frames.dat", "w");
    fclose(fy);
#endif

    // histfile = fopen("histo.dat", "ab");
    // ratefile = fopen("rates.dat", "ab");

    /* handling wrong input arguments in the command line */
    if ((argc < 6) || (argc > 10)) {
        printf("\n\nWrong number of arguments or flag values.\n\n");

        printf("\n");
        WebRtcIsacfix_version(version_number);
        printf("iSAC version %s \n\n", version_number);

        printf("Usage:\n\n");
        printf("./kenny.exe [-I] bottleneck_value infile outfile \n\n");
        printf("with:\n");

        printf("[-I]            : If -I option is specified, the coder will use\n");
        printf("                  an instantaneous Bottleneck value. If not, it\n");
        printf("                  will be an adaptive Bottleneck value.\n\n");
        printf("bottleneck_value: The value of the bottleneck provided either\n");
        printf("                  as a fixed value (e.g. 25000) or\n");
        printf("                  read from a file (e.g. bottleneck.txt)\n\n");
        printf("[-m] mode       : Mode (encoder - decoder):\n");
        printf("                    0 - float - float\n");
        printf("                    1 - float - fix\n");
        printf("                    2 - fix - float\n");
        printf("                    3 - fix - fix\n\n");
        printf("[-PLC]          : Test PLC packetlosses\n\n");
        printf("[-NB] num       : Test NB interfaces:\n");
        printf("                    1 - encNB\n");
        printf("                    2 - decNB\n\n");
        printf("infile          : Normal speech input file\n\n");
        printf("outfile         : Speech output file\n\n");
        printf("Example usage:\n\n");
        printf("./kenny.exe -I bottleneck.txt -m 1 speechIn.pcm speechOut.pcm\n\n");
        exit(0);
    }

    printf("--------------------START---------------------\n\n");
    WebRtcIsac_version(version_number);
    printf("iSAC FLOAT version %s \n", version_number);
    WebRtcIsacfix_version(version_number);
    printf("iSAC FIX version   %s \n\n", version_number);

    CodingMode = 0;
    tmp = 1;
    for (i = 1; i < argc; i++) {
        if (!strcmp("-I", argv[i])) {
            printf("\nInstantaneous BottleNeck\n");
            CodingMode = 1;
            i++;
            tmp = 0;
        }

        if (!strcmp("-m", argv[i])) {
            mode = atoi(argv[i + 1]);
            i++;
        }

        if (!strcmp("-PLC", argv[i])) {
            plc = 1;
        }

        if (!strcmp("-NB", argv[i])) {
            nbTest = atoi(argv[i + 1]);
            i++;
        }
    }

    if (mode < 0) {
        printf("\nError! Mode must be set: -m 0 \n");
        exit(0);
    }

    if (CodingMode == 0) {
        printf("\nAdaptive BottleNeck\n");
    }

    /* Get Bottleneck value */
    bottleneck = atoi(argv[2 - tmp]);
    if (bottleneck == 0) {
        sscanf(argv[2 - tmp], "%s", bottleneck_file);
        f_bn = fopen(bottleneck_file, "rb");
        if (f_bn == NULL) {
            printf("No value provided for BottleNeck and cannot read file %s.\n",
                   bottleneck_file);
            exit(0);
        } else {
            printf("reading bottleneck rates from file %s\n\n", bottleneck_file);
            if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
                /* Set pointer to beginning of file */
                fseek(f_bn, 0L, SEEK_SET);
                fscanf(f_bn, "%d", &bottleneck);
            }

            /* Bottleneck is a cosine function
             * Matlab code for writing the bottleneck file:
             * BottleNeck_10ms = 20e3 + 10e3 * cos((0:5999)/5999*2*pi);
             * fid = fopen('bottleneck.txt', 'wb');
             * fprintf(fid, '%d\n', BottleNeck_10ms); fclose(fid);
             */
        }
    } else {
        printf("\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
    }

    /* Get Input and Output files */
    sscanf(argv[argc - 2], "%s", inname);
    sscanf(argv[argc - 1], "%s", outname);

    if ((inp = fopen(inname, "rb")) == NULL) {
        printf("  iSAC: Cannot read file %s.\n", inname);
        exit(1);
    }
    if ((outp = fopen(outname, "wb")) == NULL) {
        printf("  iSAC: Cannot write file %s.\n", outname);
        exit(1);
    }
    printf("\nInput:%s\nOutput:%s\n", inname, outname);

    i = 0;
    while (outname[i] != '\0') {
        bitfilename[i] = outname[i];
        i++;
    }
    i -= 4;
    for (j = 0; j < 9; j++, i++)
        bitfilename[i] = bitending[j];
    bitfilename[i] = '\0';
    if ((bitsp = fopen(bitfilename, "wb")) == NULL) {
        printf("  iSAC: Cannot read file %s.\n", bitfilename);
        exit(1);
    }
    printf("Bitstream:%s\n\n", bitfilename);

    starttime = clock() / (double)CLOCKS_PER_SEC; /* Runtime statistics */

    /* Initialize the ISAC and BN structs */
    WebRtcIsac_create(&ISAC_main_inst);
    WebRtcIsacfix_Create(&ISACFIX_main_inst);

    BN_data.send_time = 0;
    BN_data.arrival_time = 0;
    BN_data.sample_count = 0;
    BN_data.rtp_number = 0;

    /* Initialize encoder and decoder */
    framecnt = 0;
    endfile = 0;

    if (mode == 0) { /* Encode using FLOAT, decode using FLOAT */

        printf("Coding mode: Encode using FLOAT, decode using FLOAT \n\n");

        /* Init iSAC FLOAT */
        WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
        WebRtcIsac_DecoderInit(ISAC_main_inst);
        if (CodingMode == 1) {
            err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
            if (err < 0) {
                /* exit if returned with error */
                errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                printf("\n\n Error in initialization: %d.\n\n", errtype);
                // exit(EXIT_FAILURE);
            }
        }

    } else if (mode == 1) { /* Encode using FLOAT, decode using FIX */

        printf("Coding mode: Encode using FLOAT, decode using FIX \n\n");

        /* Init iSAC FLOAT */
        WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
        WebRtcIsac_DecoderInit(ISAC_main_inst);
        if (CodingMode == 1) {
            err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
            if (err < 0) {
                /* exit if returned with error */
                errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                printf("\n\n Error in initialization: %d.\n\n", errtype);
                // exit(EXIT_FAILURE);
            }
        }

        /* Init iSAC FIX */
        WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
        WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
        if (CodingMode == 1) {
            err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
            if (err < 0) {
                /* exit if returned with error */
                errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                printf("\n\n Error in initialization: %d.\n\n", errtype);
                // exit(EXIT_FAILURE);
            }
        }
    } else if (mode == 2) { /* Encode using FIX, decode using FLOAT */

        printf("Coding mode: Encode using FIX, decode using FLOAT \n\n");

        /* Init iSAC FLOAT */
        WebRtcIsac_EncoderInit(ISAC_main_inst, CodingMode);
        WebRtcIsac_DecoderInit(ISAC_main_inst);
        if (CodingMode == 1) {
            err = WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
            if (err < 0) {
                /* exit if returned with error */
                errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                printf("\n\n Error in initialization: %d.\n\n", errtype);
                // exit(EXIT_FAILURE);
            }
        }

        /* Init iSAC FIX */
        WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
        WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
        if (CodingMode == 1) {
            err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
            if (err < 0) {
                /* exit if returned with error */
                errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                printf("\n\n Error in initialization: %d.\n\n", errtype);
                // exit(EXIT_FAILURE);
            }
        }
    } else if (mode == 3) {
        printf("Coding mode: Encode using FIX, decode using FIX \n\n");

        WebRtcIsacfix_EncoderInit(ISACFIX_main_inst, CodingMode);
        WebRtcIsacfix_DecoderInit(ISACFIX_main_inst);
        if (CodingMode == 1) {
            err = WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
            if (err < 0) {
                /* exit if returned with error */
                errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                printf("\n\n Error in initialization: %d.\n\n", errtype);
                // exit(EXIT_FAILURE);
            }
        }

    } else
        printf("Mode must be value between 0 and 3\n");
    *speechType = 1;

//#define BI_TEST 1
#ifdef BI_TEST
    err = WebRtcIsacfix_SetMaxPayloadSize(ISACFIX_main_inst, 300);
    if (err < 0) {
        /* exit if returned with error */
        errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
        printf("\n\n Error in setMaxPayloadSize: %d.\n\n", errtype);
        fclose(inp);
        fclose(outp);
        fclose(bitsp);
        return (EXIT_FAILURE);
    }
#endif

    while (endfile == 0) {
        cur_framesmpls = 0;
        while (1) {
            int stream_len_int;

            /* Read 10 ms speech block */
            if (nbTest != 1)
                endfile = readframe(shortdata, inp, FRAMESAMPLES_10ms);
            else
                endfile = readframe(shortdata, inp, (FRAMESAMPLES_10ms / 2));

            /* iSAC encoding */

            if (mode == 0 || mode == 1) {
                stream_len_int =
                    WebRtcIsac_Encode(ISAC_main_inst, shortdata, (uint8_t*)streamdata);
                if (stream_len_int < 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                    printf("\n\nError in encoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
            } else if (mode == 2 || mode == 3) {
                /* iSAC encoding */
                if (nbTest != 1) {
                    stream_len_int = WebRtcIsacfix_Encode(ISACFIX_main_inst, shortdata,
                                                          (uint8_t*)streamdata);
                } else {
                    stream_len_int =
                        WebRtcIsacfix_EncodeNb(ISACFIX_main_inst, shortdata, streamdata);
                }

                if (stream_len_int < 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                    printf("\n\nError in encoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
            }
            stream_len = (size_t)stream_len_int;

            cur_framesmpls += FRAMESAMPLES_10ms;

            /* read next bottleneck rate */
            if (f_bn != NULL) {
                if (fscanf(f_bn, "%d", &bottleneck) == EOF) {
                    /* Set pointer to beginning of file */
                    fseek(f_bn, 0L, SEEK_SET);
                    fscanf(f_bn, "%d", &bottleneck);
                }
                if (CodingMode == 1) {
                    if (mode == 0 || mode == 1)
                        WebRtcIsac_Control(ISAC_main_inst, bottleneck, framesize);
                    else if (mode == 2 || mode == 3)
                        WebRtcIsacfix_Control(ISACFIX_main_inst, bottleneck, framesize);
                }
            }

            /* exit encoder loop if the encoder returned a bitstream */
            if (stream_len != 0)
                break;
        }

        fwrite(streamdata, 1, stream_len, bitsp); /* NOTE! Writes bytes to file */

        /* simulate packet handling through NetEq and the modem */
        get_arrival_time(cur_framesmpls, stream_len, bottleneck, &BN_data);
        //*****************************
        if (1) {
            if (mode == 0) {
                err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst, streamdata,
                                                  stream_len, BN_data.rtp_number,
                                                  BN_data.arrival_time);

                if (err < 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
                /* iSAC decoding */
                declen = WebRtcIsac_Decode(ISAC_main_inst, streamdata, stream_len,
                                           decoded, speechType);
                if (declen <= 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
            } else if (mode == 1) {
                err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst, streamdata,
                                                  stream_len, BN_data.rtp_number,
                                                  BN_data.arrival_time);
                err = WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_main_inst, streamdata,
                                                      stream_len, BN_data.rtp_number,
                                                      BN_data.arrival_time);
                if (err < 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }

                declen = WebRtcIsac_Decode(ISAC_main_inst, streamdata, stream_len,
                                           decoded, speechType);

                /* iSAC decoding */
                if (plc && (framecnt + 1) % 10 == 0) {
                    if (nbTest != 2) {
                        declen =
                            (int)WebRtcIsacfix_DecodePlc(ISACFIX_main_inst, decoded, 1);
                    } else {
                        declen =
                            (int)WebRtcIsacfix_DecodePlcNb(ISACFIX_main_inst, decoded, 1);
                    }
                } else {
                    if (nbTest != 2)
                        declen = WebRtcIsacfix_Decode(ISACFIX_main_inst, streamdata,
                                                      stream_len, decoded, speechType);
                    else
                        declen = WebRtcIsacfix_DecodeNb(ISACFIX_main_inst, streamdata,
                                                        stream_len, decoded, speechType);
                }

                if (declen <= 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
            } else if (mode == 2) {
                err = WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_main_inst, streamdata,
                                                      stream_len, BN_data.rtp_number,
                                                      BN_data.arrival_time);

                err = WebRtcIsac_UpdateBwEstimate(ISAC_main_inst, streamdata,
                                                  stream_len, BN_data.rtp_number,
                                                  BN_data.arrival_time);

                if (err < 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
                /* iSAC decoding */
                declen = WebRtcIsac_Decode(ISAC_main_inst, streamdata, stream_len,
                                           decoded, speechType);
                if (declen <= 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsac_GetErrorCode(ISAC_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
            } else if (mode == 3) {
                err = WebRtcIsacfix_UpdateBwEstimate(
                          ISACFIX_main_inst, streamdata, stream_len, BN_data.rtp_number,
                          BN_data.send_time, BN_data.arrival_time);

                if (err < 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
                /* iSAC decoding */

                if (plc && (framecnt + 1) % 10 == 0) {
                    if (nbTest != 2) {
                        declen =
                            (int)WebRtcIsacfix_DecodePlc(ISACFIX_main_inst, decoded, 1);
                    } else {
                        declen =
                            (int)WebRtcIsacfix_DecodePlcNb(ISACFIX_main_inst, decoded, 1);
                    }
                } else {
                    if (nbTest != 2) {
                        declen = WebRtcIsacfix_Decode(ISACFIX_main_inst, streamdata,
                                                      stream_len, decoded, speechType);
                    } else {
                        declen = WebRtcIsacfix_DecodeNb(ISACFIX_main_inst, streamdata,
                                                        stream_len, decoded, speechType);
                    }
                }
                if (declen <= 0) {
                    /* exit if returned with error */
                    errtype = WebRtcIsacfix_GetErrorCode(ISACFIX_main_inst);
                    printf("\n\nError in decoder: %d.\n\n", errtype);
                    // exit(EXIT_FAILURE);
                }
            }

            /* Write decoded speech frame to file */
            fwrite(decoded, sizeof(int16_t), declen, outp);
        }

        fprintf(stderr, "  \rframe = %d", framecnt);
        framecnt++;

#if !defined(NDEBUG)

        totalsmpls += declen;
        totalbits += 8 * stream_len;
        kbps = (double)FS / (double)cur_framesmpls * 8.0 * stream_len / 1000.0;
        fy = fopen("bit_rate.dat", "a");
        fprintf(fy, "Frame %i = %0.14f\n", framecnt, kbps);
        fclose(fy);

#endif
    }

#if !defined(NDEBUG)
    printf("\n\ntotal bits               = %" PRIuS " bits", totalbits);
    printf("\nmeasured average bitrate = %0.3f kbits/s",
           (double)totalbits * (FS / 1000) / totalsmpls);
    printf("\n");
#endif

    /* Runtime statistics */
    runtime = (double)(clock() / (double)CLOCKS_PER_SEC - starttime);
    length_file = ((double)framecnt * (double)declen / FS);
    printf("\n\nLength of speech file: %.1f s\n", length_file);
    printf("Time to run iSAC:      %.2f s (%.2f %% of realtime)\n\n", runtime,
           (100 * runtime / length_file));
    printf("---------------------END----------------------\n");

    fclose(inp);
    fclose(outp);

    WebRtcIsac_Free(ISAC_main_inst);
    WebRtcIsacfix_Free(ISACFIX_main_inst);

    // fclose(histfile);
    // fclose(ratefile);

    return 0;
}