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,
    287                                     (uint8_t*)bitStream);
    288       int16_t ggg;
    289       if (streamLen > 0) {
    290         if((  WebRtcIsac_ReadFrameLen(codecInstance[receiverIdx],
    291                                       (short *) bitStream, &ggg))<0)
    292           printf("ERROR\n");
    293       }
    294 
    295       // Sanity check
    296       if(streamLen < 0)
    297       {
    298         printf(" Encoder error in client %d \n", senderIdx + 1);
    299         return -1;
    300       }
    301 
    302 
    303       if(streamLen > 0)
    304       {
    305         // Packet generated; model sending through a channel, do bandwidth
    306         // estimation at the receiver and decode.
    307         lenEncodedInBytes[senderIdx] += streamLen;
    308         lenAudioIn10ms[senderIdx] += (unsigned int)num10ms[senderIdx];
    309         lenEncodedInBytesTmp[senderIdx] += streamLen;
    310         lenAudioIn10msTmp[senderIdx] += (unsigned int)num10ms[senderIdx];
    311 
    312         // Print after ~5 sec.
    313         if(lenAudioIn10msTmp[senderIdx] >= 100)
    314         {
    315           numPrint[senderIdx]++;
    316           printf("  %d,  %6.3f => %6.3f ", senderIdx+1,
    317                  bottleneck[senderIdx] / 1000.0,
    318                  lenEncodedInBytesTmp[senderIdx] * 0.8 /
    319                  lenAudioIn10msTmp[senderIdx]);
    320 
    321           if(codingMode == 0)
    322           {
    323             int32_t bn;
    324             WebRtcIsac_GetUplinkBw(codecInstance[senderIdx], &bn);
    325             printf("[%d] ", bn);
    326           }
    327           //int16_t rateIndexLB;
    328           //int16_t rateIndexUB;
    329           //WebRtcIsac_GetDownLinkBwIndex(codecInstance[receiverIdx],
    330           //    &rateIndexLB, &rateIndexUB);
    331           //printf(" (%2d, %2d) ", rateIndexLB, rateIndexUB);
    332 
    333           cout << flush;
    334           lenEncodedInBytesTmp[senderIdx] = 0;
    335           lenAudioIn10msTmp[senderIdx]    = 0;
    336           //if(senderIdx == (NUM_CLIENTS - 1))
    337           //{
    338           printf("  %0.1f \n", lenAudioIn10ms[senderIdx] * 10. /1000);
    339           //}
    340 
    341           // After ~20 sec change the bottleneck.
    342           //    if((numPrint[senderIdx] == 4) && (codingMode == 0))
    343           //    {
    344           //        numPrint[senderIdx] = 0;
    345           //        if(codingMode == 0)
    346           //        {
    347           //            int newBottleneck = bottleneck[senderIdx] +
    348           //                (bottleneckChange[senderIdx] * 1000);
    349 
    350           //            if(bottleneckChange[senderIdx] > 0)
    351           //            {
    352           //                if(newBottleneck >maxBn)
    353           //                {
    354           //                    bottleneckChange[senderIdx] = -1;
    355           //                    newBottleneck = bottleneck[senderIdx] +
    356           //                        (bottleneckChange[senderIdx] * 1000);
    357           //                    if(newBottleneck > minBn)
    358           //                    {
    359           //                        bottleneck[senderIdx] = newBottleneck;
    360           //                    }
    361           //                }
    362           //                else
    363           //                {
    364           //                    bottleneck[senderIdx] = newBottleneck;
    365           //                }
    366           //            }
    367           //            else
    368           //            {
    369           //                if(newBottleneck < minBn)
    370           //                {
    371           //                    bottleneckChange[senderIdx] = 1;
    372           //                    newBottleneck = bottleneck[senderIdx] +
    373           //                        (bottleneckChange[senderIdx] * 1000);
    374           //                    if(newBottleneck < maxBn)
    375           //                    {
    376           //                        bottleneck[senderIdx] = newBottleneck;
    377           //                    }
    378           //                }
    379           //                else
    380           //                {
    381           //                    bottleneck[senderIdx] = newBottleneck;
    382           //                }
    383           //            }
    384           //        }
    385           //    }
    386         }
    387 
    388         // model a channel of given bottleneck, to get the receive timestamp
    389         get_arrival_time(num10ms[senderIdx] * samplesIn10ms[senderIdx],
    390                          streamLen, bottleneck[senderIdx], packetData[senderIdx],
    391                          encoderSampRate[senderIdx]*1000, encoderSampRate[senderIdx]*1000);
    392 
    393         // Write the arrival time.
    394         if(senderIdx == 0)
    395         {
    396           if (fwrite(&(packetData[senderIdx]->arrival_time),
    397                      sizeof(unsigned int),
    398                      1, arrivalTimeFile1) != 1) {
    399             return -1;
    400           }
    401         }
    402         else
    403         {
    404           if (fwrite(&(packetData[senderIdx]->arrival_time),
    405                      sizeof(unsigned int),
    406                      1, arrivalTimeFile2) != 1) {
    407             return -1;
    408           }
    409         }
    410 
    411         // BWE
    412         if(WebRtcIsac_UpdateBwEstimate(codecInstance[receiverIdx],
    413                                        bitStream,  streamLen, packetData[senderIdx]->rtp_number,
    414                                        packetData[senderIdx]->sample_count,
    415                                        packetData[senderIdx]->arrival_time) < 0)
    416         {
    417           printf(" BWE Error at client %d \n", receiverIdx + 1);
    418           return -1;
    419         }
    420         /**/
    421         // Decode
    422         lenDecodedAudio = WebRtcIsac_Decode(
    423             codecInstance[receiverIdx], bitStream, streamLen,
    424             audioBuff60ms, speechType);
    425         if(lenDecodedAudio < 0)
    426         {
    427           printf(" Decoder error in client %d \n", receiverIdx + 1);
    428           return -1;
    429         }
    430 
    431 
    432         if(encoderSampRate[senderIdx] == 16000)
    433         {
    434           WebRtcSpl_UpsampleBy2(audioBuff60ms, lenDecodedAudio, resampledAudio60ms,
    435                                 resamplerState[receiverIdx]);
    436           if (fwrite(resampledAudio60ms, sizeof(short), lenDecodedAudio << 1,
    437                      outFile[receiverIdx]) !=
    438               static_cast<size_t>(lenDecodedAudio << 1)) {
    439             return -1;
    440           }
    441         }
    442         else
    443         {
    444           if (fwrite(audioBuff60ms, sizeof(short), lenDecodedAudio,
    445                      outFile[receiverIdx]) !=
    446               static_cast<size_t>(lenDecodedAudio)) {
    447             return -1;
    448           }
    449         }
    450         num10ms[senderIdx] = 0;
    451       }
    452       //}
    453       //}
    454     }
    455   }
    456 }
    457