SwitchingSampRate.cc revision 0946a56023d821e0deca04029bb016ae1f23aa82
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
26using namespace std;
27
28int 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