Home | History | Annotate | Download | only in SwitchingSampRate
      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 // SwitchingSampRate.cpp : Defines the entry point for the console
     12 // application.
     13 //
     14 
     15 #include <iostream>
     16 #include "isac.h"
     17 #include "utility.h"
     18 #include "signal_processing_library.h"
     19 
     20 #define MAX_FILE_NAME  500
     21 #define MAX_NUM_CLIENTS 2
     22 
     23 
     24 #define NUM_CLIENTS 2
     25 
     26 using namespace std;
     27 
     28 int main(int argc, char* argv[])
     29 {
     30   char fileNameWB[MAX_FILE_NAME];
     31   char fileNameSWB[MAX_FILE_NAME];
     32 
     33   char outFileName[MAX_NUM_CLIENTS][MAX_FILE_NAME];
     34 
     35   FILE* inFile[MAX_NUM_CLIENTS];
     36   FILE* outFile[MAX_NUM_CLIENTS];
     37 
     38   ISACStruct* codecInstance[MAX_NUM_CLIENTS];
     39   int32_t resamplerState[MAX_NUM_CLIENTS][8];
     40 
     41   int encoderSampRate[MAX_NUM_CLIENTS];
     42 
     43   int minBn = 16000;
     44   int maxBn = 56000;
     45 
     46   int bnWB = 32000;
     47   int bnSWB = 56000;
     48 
     49   strcpy(outFileName[0], "switchSampRate_out1.pcm");
     50   strcpy(outFileName[1], "switchSampRate_out2.pcm");
     51 
     52   short clientCntr;
     53 
     54   size_t lenEncodedInBytes[MAX_NUM_CLIENTS];
     55   unsigned int lenAudioIn10ms[MAX_NUM_CLIENTS];
     56   size_t lenEncodedInBytesTmp[MAX_NUM_CLIENTS];
     57   unsigned int lenAudioIn10msTmp[MAX_NUM_CLIENTS];
     58   BottleNeckModel* packetData[MAX_NUM_CLIENTS];
     59 
     60   char versionNumber[100];
     61   short samplesIn10ms[MAX_NUM_CLIENTS];
     62   int bottleneck[MAX_NUM_CLIENTS];
     63 
     64   printf("\n\n");
     65   printf("____________________________________________\n\n");
     66   WebRtcIsac_version(versionNumber);
     67   printf("    iSAC-swb version %s\n", versionNumber);
     68   printf("____________________________________________\n");
     69 
     70 
     71   fileNameWB[0]  = '\0';
     72   fileNameSWB[0] = '\0';
     73 
     74   char myFlag[20];
     75   strcpy(myFlag, "-wb");
     76   // READ THE WIDEBAND AND SUPER-WIDEBAND FILE NAMES
     77   if(readParamString(argc, argv, myFlag, fileNameWB, MAX_FILE_NAME) <= 0)
     78   {
     79     printf("No wideband file is specified");
     80   }
     81 
     82   strcpy(myFlag, "-swb");
     83   if(readParamString(argc, argv, myFlag, fileNameSWB, MAX_FILE_NAME) <= 0)
     84   {
     85     printf("No super-wideband file is specified");
     86   }
     87 
     88   // THE FIRST CLIENT STARTS IN WIDEBAND
     89   encoderSampRate[0] = 16000;
     90   OPEN_FILE_RB(inFile[0], fileNameWB);
     91 
     92   // THE SECOND CLIENT STARTS IN SUPER-WIDEBAND
     93   encoderSampRate[1] = 32000;
     94   OPEN_FILE_RB(inFile[1], fileNameSWB);
     95 
     96   strcpy(myFlag, "-I");
     97   short codingMode = readSwitch(argc, argv, myFlag);
     98 
     99   for(clientCntr = 0; clientCntr < NUM_CLIENTS; clientCntr++)
    100   {
    101     codecInstance[clientCntr] = NULL;
    102 
    103     printf("\n");
    104     printf("Client %d\n", clientCntr + 1);
    105     printf("---------\n");
    106     printf("Starting %s",
    107            (encoderSampRate[clientCntr] == 16000)
    108            ? "wideband":"super-wideband");
    109 
    110     // Open output File Name
    111     OPEN_FILE_WB(outFile[clientCntr], outFileName[clientCntr]);
    112     printf("Output File...................... %s\n", outFileName[clientCntr]);
    113 
    114     samplesIn10ms[clientCntr] = encoderSampRate[clientCntr] * 10;
    115 
    116     if(codingMode == 1)
    117     {
    118       bottleneck[clientCntr] = (clientCntr)? bnSWB:bnWB;
    119     }
    120     else
    121     {
    122       bottleneck[clientCntr] = (clientCntr)? minBn:maxBn;
    123     }
    124 
    125     printf("Bottleneck....................... %0.3f kbits/sec \n",
    126            bottleneck[clientCntr] / 1000.0);
    127 
    128     // coding-mode
    129     printf("Encoding Mode.................... %s\n",
    130            (codingMode == 1)? "Channel-Independent (Instantaneous)":"Adaptive");
    131 
    132     lenEncodedInBytes[clientCntr] = 0;
    133     lenAudioIn10ms[clientCntr] = 0;
    134     lenEncodedInBytesTmp[clientCntr] = 0;
    135     lenAudioIn10msTmp[clientCntr] = 0;
    136 
    137     packetData[clientCntr] = (BottleNeckModel*)new(BottleNeckModel);
    138     if(packetData[clientCntr] == NULL)
    139     {
    140       printf("Could not allocate memory for packetData \n");
    141       return -1;
    142     }
    143     memset(packetData[clientCntr], 0, sizeof(BottleNeckModel));
    144     memset(resamplerState[clientCntr], 0, sizeof(int32_t) * 8);
    145   }
    146 
    147   for(clientCntr = 0; clientCntr < NUM_CLIENTS; clientCntr++)
    148   {
    149     // Create
    150     if(WebRtcIsac_Create(&codecInstance[clientCntr]))
    151     {
    152       printf("Could not creat client %d\n", clientCntr + 1);
    153       return -1;
    154     }
    155 
    156     WebRtcIsac_SetEncSampRate(codecInstance[clientCntr], encoderSampRate[clientCntr]);
    157 
    158     WebRtcIsac_SetDecSampRate(codecInstance[clientCntr],
    159                               encoderSampRate[clientCntr + (1 - ((clientCntr & 1)<<1))]);
    160 
    161     // Initialize Encoder
    162     if(WebRtcIsac_EncoderInit(codecInstance[clientCntr],
    163                               codingMode) < 0)
    164     {
    165       printf("Could not initialize client, %d\n", clientCntr + 1);
    166       return -1;
    167     }
    168 
    169     WebRtcIsac_DecoderInit(codecInstance[clientCntr]);
    170 
    171     // setup Rate if in Instantaneous mode
    172     if(codingMode != 0)
    173     {
    174       // ONLY Clients who are not in Adaptive mode
    175       if(WebRtcIsac_Control(codecInstance[clientCntr],
    176                             bottleneck[clientCntr], 30) < 0)
    177       {
    178         printf("Could not setup bottleneck and frame-size for client %d\n",
    179                clientCntr + 1);
    180         return -1;
    181       }
    182     }
    183   }
    184 
    185 
    186   size_t streamLen;
    187   short numSamplesRead;
    188   size_t lenDecodedAudio;
    189   short senderIdx;
    190   short receiverIdx;
    191 
    192   printf("\n");
    193   short num10ms[MAX_NUM_CLIENTS];
    194   memset(num10ms, 0, sizeof(short)*MAX_NUM_CLIENTS);
    195   FILE* arrivalTimeFile1 = fopen("arrivalTime1.dat", "wb");
    196   FILE* arrivalTimeFile2 = fopen("arrivalTime2.dat", "wb");
    197   short numPrint[MAX_NUM_CLIENTS];
    198   memset(numPrint, 0, sizeof(short) * MAX_NUM_CLIENTS);
    199 
    200   // Audio Buffers
    201   short silence10ms[10 * 32];
    202   memset(silence10ms, 0, 320 * sizeof(short));
    203   short audioBuff10ms[10 * 32];
    204   short audioBuff60ms[60 * 32];
    205   short resampledAudio60ms[60 * 32];
    206 
    207   unsigned short bitStream[600+600];
    208   short speechType[1];
    209 
    210   short numSampFreqChanged = 0;
    211   while(numSampFreqChanged < 10)
    212   {
    213     for(clientCntr = 0; clientCntr < NUM_CLIENTS; clientCntr++)
    214     {
    215       // Encoding/decoding for this pair of clients, if there is
    216       // audio for any of them
    217       //if(audioLeft[clientCntr] || audioLeft[clientCntr + 1])
    218       //{
    219       //for(pairCntr = 0; pairCntr < 2; pairCntr++)
    220       //{
    221       senderIdx = clientCntr; // + pairCntr;
    222       receiverIdx = 1 - clientCntr;//  + (1 - pairCntr);
    223 
    224       //if(num10ms[senderIdx] > 6)
    225       //{
    226       //    printf("Too many frames read for client %d",
    227       //        senderIdx + 1);
    228       //    return -1;
    229       //}
    230 
    231       numSamplesRead = (short)fread(audioBuff10ms, sizeof(short),
    232                                     samplesIn10ms[senderIdx], inFile[senderIdx]);
    233       if(numSamplesRead != samplesIn10ms[senderIdx])
    234       {
    235         // file finished switch encoder sampling frequency.
    236         printf("Changing Encoder Sampling frequency in client %d to ", senderIdx+1);
    237         fclose(inFile[senderIdx]);
    238         numSampFreqChanged++;
    239         if(encoderSampRate[senderIdx] == 16000)
    240         {
    241           printf("super-wideband.\n");
    242           OPEN_FILE_RB(inFile[senderIdx], fileNameSWB);
    243           encoderSampRate[senderIdx] = 32000;
    244         }
    245         else
    246         {
    247           printf("wideband.\n");
    248           OPEN_FILE_RB(inFile[senderIdx], fileNameWB);
    249           encoderSampRate[senderIdx] = 16000;
    250         }
    251         WebRtcIsac_SetEncSampRate(codecInstance[senderIdx], encoderSampRate[senderIdx]);
    252         WebRtcIsac_SetDecSampRate(codecInstance[receiverIdx], encoderSampRate[senderIdx]);
    253 
    254         samplesIn10ms[clientCntr] = encoderSampRate[clientCntr] * 10;
    255 
    256         numSamplesRead = (short)fread(audioBuff10ms, sizeof(short),
    257                                       samplesIn10ms[senderIdx], inFile[senderIdx]);
    258         if(numSamplesRead != samplesIn10ms[senderIdx])
    259         {
    260           printf(" File %s for client %d has not enough audio\n",
    261                  (encoderSampRate[senderIdx]==16000)? "wideband":"super-wideband",
    262                  senderIdx + 1);
    263           return -1;
    264         }
    265       }
    266       num10ms[senderIdx]++;
    267 
    268       // sanity check
    269       //if(num10ms[senderIdx] > 6)
    270       //{
    271       //    printf("Client %d has got more than 60 ms audio and encoded no packet.\n",
    272       //        senderIdx);
    273       //    return -1;
    274       //}
    275 
    276       // Encode
    277 
    278 
    279       int streamLen_int = WebRtcIsac_Encode(codecInstance[senderIdx],
    280                                             audioBuff10ms,
    281                                             (uint8_t*)bitStream);
    282       int16_t ggg;
    283       if (streamLen_int > 0) {
    284         if ((WebRtcIsac_ReadFrameLen(
    285                 codecInstance[receiverIdx],
    286                 reinterpret_cast<const uint8_t*>(bitStream),
    287                 &ggg)) < 0)
    288           printf("ERROR\n");
    289       }
    290 
    291       // Sanity check
    292       if(streamLen_int < 0)
    293       {
    294         printf(" Encoder error in client %d \n", senderIdx + 1);
    295         return -1;
    296       }
    297       streamLen = static_cast<size_t>(streamLen_int);
    298 
    299 
    300       if(streamLen > 0)
    301       {
    302         // Packet generated; model sending through a channel, do bandwidth
    303         // estimation at the receiver and decode.
    304         lenEncodedInBytes[senderIdx] += streamLen;
    305         lenAudioIn10ms[senderIdx] += (unsigned int)num10ms[senderIdx];
    306         lenEncodedInBytesTmp[senderIdx] += streamLen;
    307         lenAudioIn10msTmp[senderIdx] += (unsigned int)num10ms[senderIdx];
    308 
    309         // Print after ~5 sec.
    310         if(lenAudioIn10msTmp[senderIdx] >= 100)
    311         {
    312           numPrint[senderIdx]++;
    313           printf("  %d,  %6.3f => %6.3f ", senderIdx+1,
    314                  bottleneck[senderIdx] / 1000.0,
    315                  lenEncodedInBytesTmp[senderIdx] * 0.8 /
    316                  lenAudioIn10msTmp[senderIdx]);
    317 
    318           if(codingMode == 0)
    319           {
    320             int32_t bn;
    321             WebRtcIsac_GetUplinkBw(codecInstance[senderIdx], &bn);
    322             printf("[%d] ", bn);
    323           }
    324           //int16_t rateIndexLB;
    325           //int16_t rateIndexUB;
    326           //WebRtcIsac_GetDownLinkBwIndex(codecInstance[receiverIdx],
    327           //    &rateIndexLB, &rateIndexUB);
    328           //printf(" (%2d, %2d) ", rateIndexLB, rateIndexUB);
    329 
    330           cout << flush;
    331           lenEncodedInBytesTmp[senderIdx] = 0;
    332           lenAudioIn10msTmp[senderIdx]    = 0;
    333           //if(senderIdx == (NUM_CLIENTS - 1))
    334           //{
    335           printf("  %0.1f \n", lenAudioIn10ms[senderIdx] * 10. /1000);
    336           //}
    337 
    338           // After ~20 sec change the bottleneck.
    339           //    if((numPrint[senderIdx] == 4) && (codingMode == 0))
    340           //    {
    341           //        numPrint[senderIdx] = 0;
    342           //        if(codingMode == 0)
    343           //        {
    344           //            int newBottleneck = bottleneck[senderIdx] +
    345           //                (bottleneckChange[senderIdx] * 1000);
    346 
    347           //            if(bottleneckChange[senderIdx] > 0)
    348           //            {
    349           //                if(newBottleneck >maxBn)
    350           //                {
    351           //                    bottleneckChange[senderIdx] = -1;
    352           //                    newBottleneck = bottleneck[senderIdx] +
    353           //                        (bottleneckChange[senderIdx] * 1000);
    354           //                    if(newBottleneck > minBn)
    355           //                    {
    356           //                        bottleneck[senderIdx] = newBottleneck;
    357           //                    }
    358           //                }
    359           //                else
    360           //                {
    361           //                    bottleneck[senderIdx] = newBottleneck;
    362           //                }
    363           //            }
    364           //            else
    365           //            {
    366           //                if(newBottleneck < minBn)
    367           //                {
    368           //                    bottleneckChange[senderIdx] = 1;
    369           //                    newBottleneck = bottleneck[senderIdx] +
    370           //                        (bottleneckChange[senderIdx] * 1000);
    371           //                    if(newBottleneck < maxBn)
    372           //                    {
    373           //                        bottleneck[senderIdx] = newBottleneck;
    374           //                    }
    375           //                }
    376           //                else
    377           //                {
    378           //                    bottleneck[senderIdx] = newBottleneck;
    379           //                }
    380           //            }
    381           //        }
    382           //    }
    383         }
    384 
    385         // model a channel of given bottleneck, to get the receive timestamp
    386         get_arrival_time(num10ms[senderIdx] * samplesIn10ms[senderIdx],
    387                          streamLen, bottleneck[senderIdx], packetData[senderIdx],
    388                          encoderSampRate[senderIdx]*1000, encoderSampRate[senderIdx]*1000);
    389 
    390         // Write the arrival time.
    391         if(senderIdx == 0)
    392         {
    393           if (fwrite(&(packetData[senderIdx]->arrival_time),
    394                      sizeof(unsigned int),
    395                      1, arrivalTimeFile1) != 1) {
    396             return -1;
    397           }
    398         }
    399         else
    400         {
    401           if (fwrite(&(packetData[senderIdx]->arrival_time),
    402                      sizeof(unsigned int),
    403                      1, arrivalTimeFile2) != 1) {
    404             return -1;
    405           }
    406         }
    407 
    408         // BWE
    409         if (WebRtcIsac_UpdateBwEstimate(
    410                 codecInstance[receiverIdx],
    411                 reinterpret_cast<const uint8_t*>(bitStream),
    412                 streamLen,
    413                 packetData[senderIdx]->rtp_number,
    414                 packetData[senderIdx]->sample_count,
    415                 packetData[senderIdx]->arrival_time) < 0) {
    416           printf(" BWE Error at client %d \n", receiverIdx + 1);
    417           return -1;
    418         }
    419         /**/
    420         // Decode
    421         int lenDecodedAudio_int = WebRtcIsac_Decode(
    422             codecInstance[receiverIdx],
    423             reinterpret_cast<const uint8_t*>(bitStream),
    424             streamLen,
    425             audioBuff60ms,
    426             speechType);
    427         if(lenDecodedAudio_int < 0)
    428         {
    429           printf(" Decoder error in client %d \n", receiverIdx + 1);
    430           return -1;
    431         }
    432         lenDecodedAudio = static_cast<size_t>(lenDecodedAudio_int);
    433 
    434         if(encoderSampRate[senderIdx] == 16000)
    435         {
    436           WebRtcSpl_UpsampleBy2(audioBuff60ms, lenDecodedAudio, resampledAudio60ms,
    437                                 resamplerState[receiverIdx]);
    438           if (fwrite(resampledAudio60ms, sizeof(short), lenDecodedAudio << 1,
    439                      outFile[receiverIdx]) !=
    440               lenDecodedAudio << 1) {
    441             return -1;
    442           }
    443         }
    444         else
    445         {
    446           if (fwrite(audioBuff60ms, sizeof(short), lenDecodedAudio,
    447                      outFile[receiverIdx]) !=
    448               lenDecodedAudio) {
    449             return -1;
    450           }
    451         }
    452         num10ms[senderIdx] = 0;
    453       }
    454       //}
    455       //}
    456     }
    457   }
    458 }
    459