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