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