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   unsigned int lenEncodedInBytes[MAX_NUM_CLIENTS];
     55   unsigned int lenAudioIn10ms[MAX_NUM_CLIENTS];
     56   unsigned int 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     // Initialize Decoder
    170     if(WebRtcIsac_DecoderInit(codecInstance[clientCntr]) < 0)
    171     {
    172       printf("Could not initialize decoder of client %d\n",
    173              clientCntr + 1);
    174       return -1;
    175     }
    176 
    177     // setup Rate if in Instantaneous mode
    178     if(codingMode != 0)
    179     {
    180       // ONLY Clients who are not in Adaptive mode
    181       if(WebRtcIsac_Control(codecInstance[clientCntr],
    182                             bottleneck[clientCntr], 30) < 0)
    183       {
    184         printf("Could not setup bottleneck and frame-size for client %d\n",
    185                clientCntr + 1);
    186         return -1;
    187       }
    188     }
    189   }
    190 
    191 
    192   short streamLen;
    193   short numSamplesRead;
    194   short lenDecodedAudio;
    195   short senderIdx;
    196   short receiverIdx;
    197 
    198   printf("\n");
    199   short num10ms[MAX_NUM_CLIENTS];
    200   memset(num10ms, 0, sizeof(short)*MAX_NUM_CLIENTS);
    201   FILE* arrivalTimeFile1 = fopen("arrivalTime1.dat", "wb");
    202   FILE* arrivalTimeFile2 = fopen("arrivalTime2.dat", "wb");
    203   short numPrint[MAX_NUM_CLIENTS];
    204   memset(numPrint, 0, sizeof(short) * MAX_NUM_CLIENTS);
    205 
    206   // Audio Buffers
    207   short silence10ms[10 * 32];
    208   memset(silence10ms, 0, 320 * sizeof(short));
    209   short audioBuff10ms[10 * 32];
    210   short audioBuff60ms[60 * 32];
    211   short resampledAudio60ms[60 * 32];
    212 
    213   unsigned short bitStream[600+600];
    214   short speechType[1];
    215 
    216   short numSampFreqChanged = 0;
    217   while(numSampFreqChanged < 10)
    218   {
    219     for(clientCntr = 0; clientCntr < NUM_CLIENTS; clientCntr++)
    220     {
    221       // Encoding/decoding for this pair of clients, if there is
    222       // audio for any of them
    223       //if(audioLeft[clientCntr] || audioLeft[clientCntr + 1])
    224       //{
    225       //for(pairCntr = 0; pairCntr < 2; pairCntr++)
    226       //{
    227       senderIdx = clientCntr; // + pairCntr;
    228       receiverIdx = 1 - clientCntr;//  + (1 - pairCntr);
    229 
    230       //if(num10ms[senderIdx] > 6)
    231       //{
    232       //    printf("Too many frames read for client %d",
    233       //        senderIdx + 1);
    234       //    return -1;
    235       //}
    236 
    237       numSamplesRead = (short)fread(audioBuff10ms, sizeof(short),
    238                                     samplesIn10ms[senderIdx], inFile[senderIdx]);
    239       if(numSamplesRead != samplesIn10ms[senderIdx])
    240       {
    241         // file finished switch encoder sampling frequency.
    242         printf("Changing Encoder Sampling frequency in client %d to ", senderIdx+1);
    243         fclose(inFile[senderIdx]);
    244         numSampFreqChanged++;
    245         if(encoderSampRate[senderIdx] == 16000)
    246         {
    247           printf("super-wideband.\n");
    248           OPEN_FILE_RB(inFile[senderIdx], fileNameSWB);
    249           encoderSampRate[senderIdx] = 32000;
    250         }
    251         else
    252         {
    253           printf("wideband.\n");
    254           OPEN_FILE_RB(inFile[senderIdx], fileNameWB);
    255           encoderSampRate[senderIdx] = 16000;
    256         }
    257         WebRtcIsac_SetEncSampRate(codecInstance[senderIdx], encoderSampRate[senderIdx]);
    258         WebRtcIsac_SetDecSampRate(codecInstance[receiverIdx], encoderSampRate[senderIdx]);
    259 
    260         samplesIn10ms[clientCntr] = encoderSampRate[clientCntr] * 10;
    261 
    262         numSamplesRead = (short)fread(audioBuff10ms, sizeof(short),
    263                                       samplesIn10ms[senderIdx], inFile[senderIdx]);
    264         if(numSamplesRead != samplesIn10ms[senderIdx])
    265         {
    266           printf(" File %s for client %d has not enough audio\n",
    267                  (encoderSampRate[senderIdx]==16000)? "wideband":"super-wideband",
    268                  senderIdx + 1);
    269           return -1;
    270         }
    271       }
    272       num10ms[senderIdx]++;
    273 
    274       // sanity check
    275       //if(num10ms[senderIdx] > 6)
    276       //{
    277       //    printf("Client %d has got more than 60 ms audio and encoded no packet.\n",
    278       //        senderIdx);
    279       //    return -1;
    280       //}
    281 
    282       // Encode
    283 
    284 
    285       streamLen = WebRtcIsac_Encode(codecInstance[senderIdx],
    286                                     audioBuff10ms, (short*)bitStream);
    287       int16_t ggg;
    288       if (streamLen > 0) {
    289         if((  WebRtcIsac_ReadFrameLen(codecInstance[receiverIdx],
    290                                       (short *) bitStream, &ggg))<0)
    291           printf("ERROR\n");
    292       }
    293 
    294       // Sanity check
    295       if(streamLen < 0)
    296       {
    297         printf(" Encoder error in client %d \n", senderIdx + 1);
    298         return -1;
    299       }
    300 
    301 
    302       if(streamLen > 0)
    303       {
    304         // Packet generated; model sending through a channel, do bandwidth
    305         // estimation at the receiver and decode.
    306         lenEncodedInBytes[senderIdx] += streamLen;
    307         lenAudioIn10ms[senderIdx] += (unsigned int)num10ms[senderIdx];
    308         lenEncodedInBytesTmp[senderIdx] += streamLen;
    309         lenAudioIn10msTmp[senderIdx] += (unsigned int)num10ms[senderIdx];
    310 
    311         // Print after ~5 sec.
    312         if(lenAudioIn10msTmp[senderIdx] >= 100)
    313         {
    314           numPrint[senderIdx]++;
    315           printf("  %d,  %6.3f => %6.3f ", senderIdx+1,
    316                  bottleneck[senderIdx] / 1000.0,
    317                  lenEncodedInBytesTmp[senderIdx] * 0.8 /
    318                  lenAudioIn10msTmp[senderIdx]);
    319 
    320           if(codingMode == 0)
    321           {
    322             int32_t bn;
    323             WebRtcIsac_GetUplinkBw(codecInstance[senderIdx], &bn);
    324             printf("[%d] ", bn);
    325           }
    326           //int16_t rateIndexLB;
    327           //int16_t rateIndexUB;
    328           //WebRtcIsac_GetDownLinkBwIndex(codecInstance[receiverIdx],
    329           //    &rateIndexLB, &rateIndexUB);
    330           //printf(" (%2d, %2d) ", rateIndexLB, rateIndexUB);
    331 
    332           cout << flush;
    333           lenEncodedInBytesTmp[senderIdx] = 0;
    334           lenAudioIn10msTmp[senderIdx]    = 0;
    335           //if(senderIdx == (NUM_CLIENTS - 1))
    336           //{
    337           printf("  %0.1f \n", lenAudioIn10ms[senderIdx] * 10. /1000);
    338           //}
    339 
    340           // After ~20 sec change the bottleneck.
    341           //    if((numPrint[senderIdx] == 4) && (codingMode == 0))
    342           //    {
    343           //        numPrint[senderIdx] = 0;
    344           //        if(codingMode == 0)
    345           //        {
    346           //            int newBottleneck = bottleneck[senderIdx] +
    347           //                (bottleneckChange[senderIdx] * 1000);
    348 
    349           //            if(bottleneckChange[senderIdx] > 0)
    350           //            {
    351           //                if(newBottleneck >maxBn)
    352           //                {
    353           //                    bottleneckChange[senderIdx] = -1;
    354           //                    newBottleneck = bottleneck[senderIdx] +
    355           //                        (bottleneckChange[senderIdx] * 1000);
    356           //                    if(newBottleneck > minBn)
    357           //                    {
    358           //                        bottleneck[senderIdx] = newBottleneck;
    359           //                    }
    360           //                }
    361           //                else
    362           //                {
    363           //                    bottleneck[senderIdx] = newBottleneck;
    364           //                }
    365           //            }
    366           //            else
    367           //            {
    368           //                if(newBottleneck < minBn)
    369           //                {
    370           //                    bottleneckChange[senderIdx] = 1;
    371           //                    newBottleneck = bottleneck[senderIdx] +
    372           //                        (bottleneckChange[senderIdx] * 1000);
    373           //                    if(newBottleneck < maxBn)
    374           //                    {
    375           //                        bottleneck[senderIdx] = newBottleneck;
    376           //                    }
    377           //                }
    378           //                else
    379           //                {
    380           //                    bottleneck[senderIdx] = newBottleneck;
    381           //                }
    382           //            }
    383           //        }
    384           //    }
    385         }
    386 
    387         // model a channel of given bottleneck, to get the receive timestamp
    388         get_arrival_time(num10ms[senderIdx] * samplesIn10ms[senderIdx],
    389                          streamLen, bottleneck[senderIdx], packetData[senderIdx],
    390                          encoderSampRate[senderIdx]*1000, encoderSampRate[senderIdx]*1000);
    391 
    392         // Write the arrival time.
    393         if(senderIdx == 0)
    394         {
    395           if (fwrite(&(packetData[senderIdx]->arrival_time),
    396                      sizeof(unsigned int),
    397                      1, arrivalTimeFile1) != 1) {
    398             return -1;
    399           }
    400         }
    401         else
    402         {
    403           if (fwrite(&(packetData[senderIdx]->arrival_time),
    404                      sizeof(unsigned int),
    405                      1, arrivalTimeFile2) != 1) {
    406             return -1;
    407           }
    408         }
    409 
    410         // BWE
    411         if(WebRtcIsac_UpdateBwEstimate(codecInstance[receiverIdx],
    412                                        bitStream,  streamLen, packetData[senderIdx]->rtp_number,
    413                                        packetData[senderIdx]->sample_count,
    414                                        packetData[senderIdx]->arrival_time) < 0)
    415         {
    416           printf(" BWE Error at client %d \n", receiverIdx + 1);
    417           return -1;
    418         }
    419         /**/
    420         // Decode
    421         lenDecodedAudio = WebRtcIsac_Decode(
    422             codecInstance[receiverIdx], bitStream, streamLen,
    423             audioBuff60ms, speechType);
    424         if(lenDecodedAudio < 0)
    425         {
    426           printf(" Decoder error in client %d \n", receiverIdx + 1);
    427           return -1;
    428         }
    429 
    430 
    431         if(encoderSampRate[senderIdx] == 16000)
    432         {
    433           WebRtcSpl_UpsampleBy2(audioBuff60ms, lenDecodedAudio, resampledAudio60ms,
    434                                 resamplerState[receiverIdx]);
    435           if (fwrite(resampledAudio60ms, sizeof(short), lenDecodedAudio << 1,
    436                      outFile[receiverIdx]) !=
    437               static_cast<size_t>(lenDecodedAudio << 1)) {
    438             return -1;
    439           }
    440         }
    441         else
    442         {
    443           if (fwrite(audioBuff60ms, sizeof(short), lenDecodedAudio,
    444                      outFile[receiverIdx]) !=
    445               static_cast<size_t>(lenDecodedAudio)) {
    446             return -1;
    447           }
    448         }
    449         num10ms[senderIdx] = 0;
    450       }
    451       //}
    452       //}
    453     }
    454   }
    455 }
    456