Home | History | Annotate | Download | only in test
      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 /* kenny.c  - Main function for the iSAC coder */
     12 
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 #include <time.h>
     17 
     18 #ifdef WIN32
     19 #include "windows.h"
     20 #define CLOCKS_PER_SEC  1000
     21 #endif
     22 
     23 #include <ctype.h>
     24 #include <math.h>
     25 
     26 /* include API */
     27 #include "isac.h"
     28 #include "utility.h"
     29 //#include "commonDefs.h"
     30 
     31 /* max number of samples per frame (= 60 ms frame) */
     32 #define MAX_FRAMESAMPLES_SWB                1920
     33 /* number of samples per 10ms frame */
     34 #define FRAMESAMPLES_SWB_10ms               320
     35 #define FRAMESAMPLES_WB_10ms                160
     36 
     37 /* sampling frequency (Hz) */
     38 #define FS_SWB                               32000
     39 #define FS_WB                                16000
     40 
     41 //#define CHANGE_OUTPUT_NAME
     42 
     43 #ifdef HAVE_DEBUG_INFO
     44     #include "debugUtility.h"
     45     debugStruct debugInfo;
     46 #endif
     47 
     48 unsigned long framecnt = 0;
     49 
     50 int main(int argc, char* argv[])
     51 {
     52     //--- File IO ----
     53     FILE* inp;
     54     FILE* outp;
     55     char inname[500];
     56     char outname[500];
     57 
     58     /* Runtime statistics */
     59     double        rate;
     60     double        rateRCU;
     61     unsigned long totalbits = 0;
     62     unsigned long totalBitsRCU = 0;
     63     unsigned long totalsmpls =0;
     64 
     65     int32_t   bottleneck = 39;
     66     int16_t   frameSize = 30;           /* ms */
     67     int16_t   codingMode = 1;
     68     int16_t   shortdata[FRAMESAMPLES_SWB_10ms];
     69     int16_t   decoded[MAX_FRAMESAMPLES_SWB];
     70     //uint16_t  streamdata[1000];
     71     int16_t   speechType[1];
     72     int16_t   payloadLimit;
     73     int32_t   rateLimit;
     74     ISACStruct*   ISAC_main_inst;
     75 
     76     int16_t   stream_len = 0;
     77     int16_t   declen = 0;
     78     int16_t   err;
     79     int16_t   cur_framesmpls;
     80     int           endfile;
     81 #ifdef WIN32
     82     double        length_file;
     83     double        runtime;
     84     char          outDrive[10];
     85     char          outPath[500];
     86     char          outPrefix[500];
     87     char          outSuffix[500];
     88     char          bitrateFileName[500];
     89     FILE*         bitrateFile;
     90     double        starttime;
     91     double        rateLB = 0;
     92     double        rateUB = 0;
     93 #endif
     94     FILE*         histFile;
     95     FILE*         averageFile;
     96     int           sampFreqKHz;
     97     int           samplesIn10Ms;
     98     int16_t   maxStreamLen = 0;
     99     char          histFileName[500];
    100     char          averageFileName[500];
    101     unsigned int  hist[600];
    102     unsigned int  tmpSumStreamLen = 0;
    103     unsigned int  packetCntr = 0;
    104     unsigned int  lostPacketCntr = 0;
    105     uint16_t  payload[600];
    106     uint16_t  payloadRCU[600];
    107     uint16_t  packetLossPercent = 0;
    108     int16_t   rcuStreamLen = 0;
    109 	int onlyEncode;
    110 	int onlyDecode;
    111 
    112 
    113     BottleNeckModel packetData;
    114 	packetData.arrival_time  = 0;
    115 	packetData.sample_count  = 0;
    116 	packetData.rtp_number    = 0;
    117     memset(hist, 0, sizeof(hist));
    118 
    119     /* handling wrong input arguments in the command line */
    120     if(argc < 5)
    121     {
    122 		int size;
    123 		WebRtcIsac_AssignSize(&size);
    124 
    125         printf("\n\nWrong number of arguments or flag values.\n\n");
    126 
    127         printf("Usage:\n\n");
    128         printf("%s infile outfile -bn bottelneck [options] \n\n", argv[0]);
    129         printf("with:\n");
    130         printf("-I................... indicates encoding in instantaneous mode.\n");
    131         printf("-bn bottleneck....... the value of the bottleneck in bit/sec, e.g. 39742,\n");
    132 		printf("                      in instantaneous (channel-independent) mode.\n\n");
    133         printf("infile............... Normal speech input file\n\n");
    134         printf("outfile.............. Speech output file\n\n");
    135         printf("OPTIONS\n");
    136         printf("-------\n");
    137         printf("-fs sampFreq......... sampling frequency of codec 16 or 32 (default) kHz.\n");
    138         printf("-plim payloadLim..... payload limit in bytes,\n");
    139         printf("                      default is the maximum possible.\n");
    140         printf("-rlim rateLim........ rate limit in bits/sec, \n");
    141         printf("                      default is the maimum possible.\n");
    142         printf("-h file.............. record histogram and *append* to 'file'.\n");
    143         printf("-ave file............ record average rate of 3 sec intervales and *append* to 'file'.\n");
    144         printf("-ploss............... packet-loss percentage.\n");
    145 		printf("-enc................. do only encoding and store the bit-stream\n");
    146 		printf("-dec................. the input file is a bit-stream, decode it.\n");
    147 
    148         printf("\n");
    149         printf("Example usage:\n\n");
    150         printf("%s speechIn.pcm speechOut.pcm -B 40000 -fs 32 \n\n", argv[0]);
    151 
    152 		printf("structure size %d bytes\n", size);
    153 
    154         exit(0);
    155     }
    156 
    157 
    158 
    159     /* Get Bottleneck value */
    160     bottleneck = readParamInt(argc, argv, "-bn", 50000);
    161     fprintf(stderr,"\nfixed bottleneck rate of %d bits/s\n\n", bottleneck);
    162 
    163     /* Get Input and Output files */
    164     sscanf(argv[1], "%s", inname);
    165     sscanf(argv[2], "%s", outname);
    166     codingMode = readSwitch(argc, argv, "-I");
    167     sampFreqKHz = (int16_t)readParamInt(argc, argv, "-fs", 32);
    168     if(readParamString(argc, argv, "-h", histFileName, 500) > 0)
    169     {
    170         histFile = fopen(histFileName, "a");
    171         if(histFile == NULL)
    172         {
    173             printf("cannot open hist file %s", histFileName);
    174             exit(0);
    175         }
    176     }
    177     else
    178     {
    179         // NO recording of hitstogram
    180         histFile = NULL;
    181     }
    182 
    183 
    184     packetLossPercent = readParamInt(argc, argv, "-ploss", 0);
    185 
    186     if(readParamString(argc, argv, "-ave", averageFileName, 500) > 0)
    187     {
    188         averageFile = fopen(averageFileName, "a");
    189         if(averageFile == NULL)
    190         {
    191             printf("cannot open file to write rate %s", averageFileName);
    192             exit(0);
    193         }
    194     }
    195     else
    196     {
    197         averageFile = NULL;
    198     }
    199 
    200 	onlyEncode = readSwitch(argc, argv, "-enc");
    201 	onlyDecode = readSwitch(argc, argv, "-dec");
    202 
    203 
    204     switch(sampFreqKHz)
    205     {
    206     case 16:
    207         {
    208             samplesIn10Ms = 160;
    209             break;
    210         }
    211     case 32:
    212         {
    213             samplesIn10Ms = 320;
    214             break;
    215         }
    216     default:
    217         printf("A sampling frequency of %d kHz is not supported,\
    218 valid values are 8 and 16.\n", sampFreqKHz);
    219         exit(-1);
    220     }
    221     payloadLimit = (int16_t)readParamInt(argc, argv, "-plim", 400);
    222     rateLimit = readParamInt(argc, argv, "-rlim", 106800);
    223 
    224     if ((inp = fopen(inname,"rb")) == NULL) {
    225         printf("  iSAC: Cannot read file %s.\n", inname);
    226         exit(1);
    227     }
    228     if ((outp = fopen(outname,"wb")) == NULL) {
    229         printf("  iSAC: Cannot write file %s.\n", outname);
    230         exit(1);
    231     }
    232 
    233 #ifdef WIN32
    234     _splitpath(outname, outDrive, outPath, outPrefix, outSuffix);
    235     _makepath(bitrateFileName, outDrive, outPath, "bitrate", ".txt");
    236 
    237     bitrateFile = fopen(bitrateFileName, "a");
    238     fprintf(bitrateFile, "%  %%s  \n", inname);
    239 #endif
    240 
    241     printf("\n");
    242     printf("Input.................... %s\n", inname);
    243     printf("Output................... %s\n", outname);
    244     printf("Encoding Mode............ %s\n",
    245         (codingMode == 1)? "Channel-Independent":"Channel-Adaptive");
    246     printf("Bottleneck............... %d bits/sec\n", bottleneck);
    247     printf("Packet-loss Percentage... %d\n", packetLossPercent);
    248     printf("\n");
    249 
    250 #ifdef WIN32
    251     starttime = clock()/(double)CLOCKS_PER_SEC; /* Runtime statistics */
    252 #endif
    253 
    254     /* Initialize the ISAC and BN structs */
    255     err = WebRtcIsac_Create(&ISAC_main_inst);
    256 
    257     WebRtcIsac_SetEncSampRate(ISAC_main_inst, sampFreqKHz * 1000);
    258     WebRtcIsac_SetDecSampRate(ISAC_main_inst, sampFreqKHz >= 32 ? 32000 :
    259         16000);
    260     /* Error check */
    261     if (err < 0) {
    262         fprintf(stderr,"\n\n Error in create.\n\n");
    263         exit(EXIT_FAILURE);
    264     }
    265 
    266     framecnt = 0;
    267     endfile     = 0;
    268 
    269     /* Initialize encoder and decoder */
    270     if(WebRtcIsac_EncoderInit(ISAC_main_inst, codingMode) < 0)
    271     {
    272         printf("cannot initialize encoder\n");
    273         return -1;
    274     }
    275     if(WebRtcIsac_DecoderInit(ISAC_main_inst) < 0)
    276     {
    277         printf("cannot initialize decoder\n");
    278         return -1;
    279     }
    280 
    281     //{
    282     //    int32_t b1, b2;
    283     //    FILE* fileID = fopen("GetBNTest.txt", "w");
    284     //    b2 = 32100;
    285     //    while(b2 <= 52000)
    286     //    {
    287     //        WebRtcIsac_Control(ISAC_main_inst, b2, frameSize);
    288     //        WebRtcIsac_GetUplinkBw(ISAC_main_inst, &b1);
    289     //        fprintf(fileID, "%5d %5d\n", b2, b1);
    290     //        b2 += 10;
    291     //    }
    292     //}
    293 
    294     if(codingMode == 1)
    295     {
    296         if(WebRtcIsac_Control(ISAC_main_inst, bottleneck, frameSize) < 0)
    297         {
    298             printf("cannot set bottleneck\n");
    299             return -1;
    300         }
    301     }
    302     else
    303     {
    304         if(WebRtcIsac_ControlBwe(ISAC_main_inst, 15000, 30, 1) < 0)
    305         {
    306             printf("cannot configure BWE\n");
    307             return -1;
    308         }
    309     }
    310 
    311     if(WebRtcIsac_SetMaxPayloadSize(ISAC_main_inst, payloadLimit) < 0)
    312     {
    313         printf("cannot set maximum payload size %d.\n", payloadLimit);
    314         return -1;
    315     }
    316 
    317     if (rateLimit < 106800) {
    318         if(WebRtcIsac_SetMaxRate(ISAC_main_inst, rateLimit) < 0)
    319         {
    320             printf("cannot set the maximum rate %d.\n", rateLimit);
    321             return -1;
    322         }
    323     }
    324 
    325     //=====================================
    326 //#ifdef HAVE_DEBUG_INFO
    327 //    if(setupDebugStruct(&debugInfo) < 0)
    328 //    {
    329 //        exit(1);
    330 //    }
    331 //#endif
    332 
    333     while (endfile == 0)
    334     {
    335         fprintf(stderr,"  \rframe = %7li", framecnt);
    336 
    337         //============== Readind from the file and encoding =================
    338         cur_framesmpls = 0;
    339         stream_len = 0;
    340 
    341 
    342 		if(onlyDecode)
    343 		{
    344 			uint8_t auxUW8;
    345                         size_t auxSizet;
    346 			if(fread(&auxUW8, sizeof(uint8_t), 1, inp) < 1)
    347 			{
    348 				break;
    349 			}
    350 			stream_len = ((uint8_t)auxUW8) << 8;
    351 			if(fread(&auxUW8, sizeof(uint8_t), 1, inp) < 1)
    352 			{
    353 				break;
    354 			}
    355 			stream_len |= (uint16_t)auxUW8;
    356                         auxSizet = (size_t)stream_len;
    357                         if(fread(payload, 1, auxSizet, inp) < auxSizet)
    358 			{
    359 				printf("last payload is corrupted\n");
    360 				break;
    361 			}
    362 		}
    363 		else
    364 		{
    365 			while(stream_len == 0)
    366 			{
    367 				// Read 10 ms speech block
    368 				endfile = readframe(shortdata, inp, samplesIn10Ms);
    369 				if(endfile)
    370 				{
    371 					break;
    372 				}
    373 				cur_framesmpls += samplesIn10Ms;
    374 
    375 				//-------- iSAC encoding ---------
    376                                 stream_len = WebRtcIsac_Encode(
    377                                         ISAC_main_inst,
    378                                         shortdata,
    379                                         (uint8_t*)payload);
    380 
    381 				if(stream_len < 0)
    382 				{
    383 					// exit if returned with error
    384 					//errType=WebRtcIsac_GetErrorCode(ISAC_main_inst);
    385 					fprintf(stderr,"\nError in encoder\n");
    386 					getchar();
    387 					exit(EXIT_FAILURE);
    388 				}
    389 
    390 
    391 			}
    392 			//===================================================================
    393 			if(endfile)
    394 			{
    395 				break;
    396 			}
    397 
    398 			rcuStreamLen = WebRtcIsac_GetRedPayload(ISAC_main_inst, (int16_t*)payloadRCU);
    399 
    400 			get_arrival_time(cur_framesmpls, stream_len, bottleneck, &packetData,
    401 				sampFreqKHz * 1000, sampFreqKHz * 1000);
    402 			if(WebRtcIsac_UpdateBwEstimate(ISAC_main_inst,
    403 				payload,  stream_len, packetData.rtp_number,
    404 				packetData.sample_count,
    405 				packetData.arrival_time) < 0)
    406 			{
    407 				printf(" BWE Error at client\n");
    408 				return -1;
    409 			}
    410 		}
    411 
    412         if(endfile)
    413         {
    414             break;
    415         }
    416 
    417         maxStreamLen = (stream_len > maxStreamLen)? stream_len:maxStreamLen;
    418         packetCntr++;
    419 
    420         hist[stream_len]++;
    421         if(averageFile != NULL)
    422         {
    423             tmpSumStreamLen += stream_len;
    424             if(packetCntr == 100)
    425             {
    426                 // kbps
    427                 fprintf(averageFile, "%8.3f ", (double)tmpSumStreamLen * 8.0 / (30.0 * packetCntr));
    428                 packetCntr = 0;
    429                 tmpSumStreamLen = 0;
    430             }
    431         }
    432 
    433 		if(onlyEncode)
    434 		{
    435                   uint8_t auxUW8;
    436                   auxUW8 = (uint8_t)(((stream_len & 0x7F00) >> 8) & 0xFF);
    437                   if (fwrite(&auxUW8, sizeof(uint8_t), 1, outp) != 1) {
    438                     return -1;
    439                   }
    440 
    441                   auxUW8 = (uint8_t)(stream_len & 0xFF);
    442                   if (fwrite(&auxUW8, sizeof(uint8_t), 1, outp) != 1) {
    443                     return -1;
    444                   }
    445                   if (fwrite(payload, 1, stream_len,
    446                              outp) != (size_t)stream_len) {
    447                     return -1;
    448                   }
    449 		}
    450 		else
    451 		{
    452 
    453 			//======================= iSAC decoding ===========================
    454 
    455 			if((rand() % 100) < packetLossPercent)
    456 			{
    457 				declen = WebRtcIsac_DecodeRcu(ISAC_main_inst, payloadRCU,
    458 					rcuStreamLen, decoded, speechType);
    459 				lostPacketCntr++;
    460 			}
    461 			else
    462 			{
    463 				declen = WebRtcIsac_Decode(ISAC_main_inst, payload,
    464 					stream_len, decoded, speechType);
    465 			}
    466 			if(declen <= 0)
    467 			{
    468 				//errType=WebRtcIsac_GetErrorCode(ISAC_main_inst);
    469 				fprintf(stderr,"\nError in decoder.\n");
    470 				getchar();
    471 				exit(1);
    472 			}
    473 
    474 			// Write decoded speech frame to file
    475                         if (fwrite(decoded, sizeof(int16_t),
    476                                    declen, outp) != (size_t)declen) {
    477                           return -1;
    478                         }
    479 			cur_framesmpls = declen;
    480 		}
    481         // Update Statistics
    482         framecnt++;
    483         totalsmpls += cur_framesmpls;
    484         if(stream_len > 0)
    485         {
    486             totalbits += 8 * stream_len;
    487         }
    488         if(rcuStreamLen > 0)
    489         {
    490             totalBitsRCU += 8 * rcuStreamLen;
    491         }
    492     }
    493 
    494     rate =    ((double)totalbits    * (sampFreqKHz)) / (double)totalsmpls;
    495     rateRCU = ((double)totalBitsRCU * (sampFreqKHz)) / (double)totalsmpls;
    496 
    497     printf("\n\n");
    498     printf("Sampling Rate......................... %d kHz\n", sampFreqKHz);
    499     printf("Payload Limit......................... %d bytes \n", payloadLimit);
    500     printf("Rate Limit............................ %d bits/sec \n", rateLimit);
    501 
    502 #ifdef WIN32
    503 #ifdef HAVE_DEBUG_INFO
    504     rateLB = ((double)debugInfo.lbBytes * 8. *
    505               (sampFreqKHz)) / (double)totalsmpls;
    506     rateUB = ((double)debugInfo.ubBytes * 8. *
    507               (sampFreqKHz)) / (double)totalsmpls;
    508 #endif
    509 
    510     fprintf(bitrateFile, "%d  %10u     %d     %6.3f  %6.3f    %6.3f\n",
    511         sampFreqKHz,
    512         framecnt,
    513         bottleneck,
    514         rateLB,
    515         rateUB,
    516         rate);
    517     fclose(bitrateFile);
    518 #endif   // WIN32
    519 
    520     printf("\n");
    521     printf("Measured bit-rate..................... %0.3f kbps\n", rate);
    522     printf("Measured RCU bit-ratre................ %0.3f kbps\n", rateRCU);
    523     printf("Maximum bit-rate/payloadsize.......... %0.3f / %d\n",
    524         maxStreamLen * 8 / 0.03, maxStreamLen);
    525     printf("Measured packet-loss.................. %0.1f%% \n",
    526         100.0f * (float)lostPacketCntr / (float)packetCntr);
    527 
    528 //#ifdef HAVE_DEBUG_INFO
    529 //    printf("Measured lower-band bit-rate.......... %0.3f kbps (%.0f%%)\n",
    530 //        rateLB, (double)(rateLB) * 100. /(double)(rate));
    531 //    printf("Measured upper-band bit-rate.......... %0.3f kbps (%.0f%%)\n",
    532 //        rateUB, (double)(rateUB) * 100. /(double)(rate));
    533 //
    534 //    printf("Maximum payload lower-band............ %d bytes (%0.3f kbps)\n",
    535 //        debugInfo.maxPayloadLB, debugInfo.maxPayloadLB * 8.0 / 0.03);
    536 //    printf("Maximum payload upper-band............ %d bytes (%0.3f kbps)\n",
    537 //        debugInfo.maxPayloadUB, debugInfo.maxPayloadUB * 8.0 / 0.03);
    538 //#endif
    539 
    540     printf("\n");
    541 
    542     /* Runtime statistics */
    543 #ifdef WIN32
    544     runtime = (double)(clock()/(double)CLOCKS_PER_SEC-starttime);
    545     length_file = ((double)framecnt*(double)declen/(sampFreqKHz*1000));
    546     printf("Length of speech file................ %.1f s\n", length_file);
    547     printf("Time to run iSAC..................... %.2f s (%.2f %% of realtime)\n\n",
    548         runtime, (100*runtime/length_file));
    549 #endif
    550     printf("\n\n_______________________________________________\n");
    551 
    552     if(histFile != NULL)
    553     {
    554         int n;
    555         for(n = 0; n < 600; n++)
    556         {
    557             fprintf(histFile, "%6d ", hist[n]);
    558         }
    559         fprintf(histFile, "\n");
    560         fclose(histFile);
    561     }
    562     if(averageFile != NULL)
    563     {
    564         if(packetCntr > 0)
    565         {
    566             fprintf(averageFile, "%8.3f ", (double)tmpSumStreamLen * 8.0 / (30.0 * packetCntr));
    567         }
    568         fprintf(averageFile, "\n");
    569         fclose(averageFile);
    570     }
    571 
    572     fclose(inp);
    573     fclose(outp);
    574 
    575     WebRtcIsac_Free(ISAC_main_inst);
    576 
    577 
    578 #ifdef CHANGE_OUTPUT_NAME
    579     {
    580         char* p;
    581         char myExt[50];
    582         char bitRateStr[10];
    583         char newOutName[500];
    584         strcpy(newOutName, outname);
    585 
    586         myExt[0] = '\0';
    587         p = strchr(newOutName, '.');
    588         if(p != NULL)
    589         {
    590             strcpy(myExt, p);
    591             *p = '_';
    592             p++;
    593             *p = '\0';
    594         }
    595         else
    596         {
    597             strcat(newOutName, "_");
    598         }
    599         sprintf(bitRateStr, "%0.0fkbps", rate);
    600         strcat(newOutName, bitRateStr);
    601         strcat(newOutName, myExt);
    602         rename(outname, newOutName);
    603     }
    604 #endif
    605     exit(0);
    606 }
    607 
    608 
    609 #ifdef HAVE_DEBUG_INFO
    610 int setupDebugStruct(debugStruct* str)
    611 {
    612     str->prevPacketLost = 0;
    613     str->currPacketLost = 0;
    614 
    615     OPEN_FILE_WB(str->res0to4FilePtr,     "Res0to4.dat");
    616     OPEN_FILE_WB(str->res4to8FilePtr,     "Res4to8.dat");
    617     OPEN_FILE_WB(str->res8to12FilePtr,    "Res8to12.dat");
    618     OPEN_FILE_WB(str->res8to16FilePtr,    "Res8to16.dat");
    619 
    620     OPEN_FILE_WB(str->res0to4DecFilePtr,  "Res0to4Dec.dat");
    621     OPEN_FILE_WB(str->res4to8DecFilePtr,  "Res4to8Dec.dat");
    622     OPEN_FILE_WB(str->res8to12DecFilePtr, "Res8to12Dec.dat");
    623     OPEN_FILE_WB(str->res8to16DecFilePtr, "Res8to16Dec.dat");
    624 
    625     OPEN_FILE_WB(str->in0to4FilePtr,      "in0to4.dat");
    626     OPEN_FILE_WB(str->in4to8FilePtr,      "in4to8.dat");
    627     OPEN_FILE_WB(str->in8to12FilePtr,     "in8to12.dat");
    628     OPEN_FILE_WB(str->in8to16FilePtr,     "in8to16.dat");
    629 
    630     OPEN_FILE_WB(str->out0to4FilePtr,     "out0to4.dat");
    631     OPEN_FILE_WB(str->out4to8FilePtr,     "out4to8.dat");
    632     OPEN_FILE_WB(str->out8to12FilePtr,    "out8to12.dat");
    633     OPEN_FILE_WB(str->out8to16FilePtr,    "out8to16.dat");
    634     OPEN_FILE_WB(str->fftFilePtr,         "riFFT.dat");
    635     OPEN_FILE_WB(str->fftDecFilePtr,      "riFFTDec.dat");
    636 
    637     OPEN_FILE_WB(str->arrivalTime,        NULL/*"ArivalTime.dat"*/);
    638     str->lastArrivalTime = 0;
    639 
    640     str->maxPayloadLB = 0;
    641     str->maxPayloadUB = 0;
    642     str->lbBytes = 0;
    643     str->ubBytes = 0;
    644 
    645     return 0;
    646 };
    647 #endif
    648