blob: 549163fc44d42664b842b8c9bcf914149ef65798 [file] [log] [blame]
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// SwitchingSampRate.cpp : Defines the entry point for the console
// application.
//
#include <iostream>
#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "modules/audio_coding/codecs/isac/main/include/isac.h"
#include "modules/audio_coding/codecs/isac/main/util/utility.h"
#define MAX_FILE_NAME 500
#define MAX_NUM_CLIENTS 2
#define NUM_CLIENTS 2
int main(int argc, char* argv[]) {
char fileNameWB[MAX_FILE_NAME];
char fileNameSWB[MAX_FILE_NAME];
char outFileName[MAX_NUM_CLIENTS][MAX_FILE_NAME];
FILE* inFile[MAX_NUM_CLIENTS];
FILE* outFile[MAX_NUM_CLIENTS];
ISACStruct* codecInstance[MAX_NUM_CLIENTS];
int32_t resamplerState[MAX_NUM_CLIENTS][8];
int encoderSampRate[MAX_NUM_CLIENTS];
int minBn = 16000;
int maxBn = 56000;
int bnWB = 32000;
int bnSWB = 56000;
strcpy(outFileName[0], "switchSampRate_out1.pcm");
strcpy(outFileName[1], "switchSampRate_out2.pcm");
short clientCntr;
size_t lenEncodedInBytes[MAX_NUM_CLIENTS];
unsigned int lenAudioIn10ms[MAX_NUM_CLIENTS];
size_t lenEncodedInBytesTmp[MAX_NUM_CLIENTS];
unsigned int lenAudioIn10msTmp[MAX_NUM_CLIENTS];
BottleNeckModel* packetData[MAX_NUM_CLIENTS];
char versionNumber[100];
short samplesIn10ms[MAX_NUM_CLIENTS];
int bottleneck[MAX_NUM_CLIENTS];
printf("\n\n");
printf("____________________________________________\n\n");
WebRtcIsac_version(versionNumber);
printf(" iSAC-swb version %s\n", versionNumber);
printf("____________________________________________\n");
fileNameWB[0] = '\0';
fileNameSWB[0] = '\0';
char myFlag[20];
strcpy(myFlag, "-wb");
// READ THE WIDEBAND AND SUPER-WIDEBAND FILE NAMES
if (readParamString(argc, argv, myFlag, fileNameWB, MAX_FILE_NAME) <= 0) {
printf("No wideband file is specified");
}
strcpy(myFlag, "-swb");
if (readParamString(argc, argv, myFlag, fileNameSWB, MAX_FILE_NAME) <= 0) {
printf("No super-wideband file is specified");
}
// THE FIRST CLIENT STARTS IN WIDEBAND
encoderSampRate[0] = 16000;
OPEN_FILE_RB(inFile[0], fileNameWB);
// THE SECOND CLIENT STARTS IN SUPER-WIDEBAND
encoderSampRate[1] = 32000;
OPEN_FILE_RB(inFile[1], fileNameSWB);
strcpy(myFlag, "-I");
short codingMode = readSwitch(argc, argv, myFlag);
for (clientCntr = 0; clientCntr < NUM_CLIENTS; clientCntr++) {
codecInstance[clientCntr] = NULL;
printf("\n");
printf("Client %d\n", clientCntr + 1);
printf("---------\n");
printf("Starting %s", (encoderSampRate[clientCntr] == 16000)
? "wideband"
: "super-wideband");
// Open output File Name
OPEN_FILE_WB(outFile[clientCntr], outFileName[clientCntr]);
printf("Output File...................... %s\n", outFileName[clientCntr]);
samplesIn10ms[clientCntr] = encoderSampRate[clientCntr] * 10;
if (codingMode == 1) {
bottleneck[clientCntr] = (clientCntr) ? bnSWB : bnWB;
} else {
bottleneck[clientCntr] = (clientCntr) ? minBn : maxBn;
}
printf("Bottleneck....................... %0.3f kbits/sec \n",
bottleneck[clientCntr] / 1000.0);
// coding-mode
printf(
"Encoding Mode.................... %s\n",
(codingMode == 1) ? "Channel-Independent (Instantaneous)" : "Adaptive");
lenEncodedInBytes[clientCntr] = 0;
lenAudioIn10ms[clientCntr] = 0;
lenEncodedInBytesTmp[clientCntr] = 0;
lenAudioIn10msTmp[clientCntr] = 0;
packetData[clientCntr] = (BottleNeckModel*)new (BottleNeckModel);
if (packetData[clientCntr] == NULL) {
printf("Could not allocate memory for packetData \n");
return -1;
}
memset(packetData[clientCntr], 0, sizeof(BottleNeckModel));
memset(resamplerState[clientCntr], 0, sizeof(int32_t) * 8);
}
for (clientCntr = 0; clientCntr < NUM_CLIENTS; clientCntr++) {
// Create
if (WebRtcIsac_Create(&codecInstance[clientCntr])) {
printf("Could not creat client %d\n", clientCntr + 1);
return -1;
}
WebRtcIsac_SetEncSampRate(codecInstance[clientCntr],
encoderSampRate[clientCntr]);
WebRtcIsac_SetDecSampRate(
codecInstance[clientCntr],
encoderSampRate[clientCntr + (1 - ((clientCntr & 1) << 1))]);
// Initialize Encoder
if (WebRtcIsac_EncoderInit(codecInstance[clientCntr], codingMode) < 0) {
printf("Could not initialize client, %d\n", clientCntr + 1);
return -1;
}
WebRtcIsac_DecoderInit(codecInstance[clientCntr]);
// setup Rate if in Instantaneous mode
if (codingMode != 0) {
// ONLY Clients who are not in Adaptive mode
if (WebRtcIsac_Control(codecInstance[clientCntr], bottleneck[clientCntr],
30) < 0) {
printf("Could not setup bottleneck and frame-size for client %d\n",
clientCntr + 1);
return -1;
}
}
}
size_t streamLen;
short numSamplesRead;
size_t lenDecodedAudio;
short senderIdx;
short receiverIdx;
printf("\n");
short num10ms[MAX_NUM_CLIENTS];
memset(num10ms, 0, sizeof(short) * MAX_NUM_CLIENTS);
FILE* arrivalTimeFile1 = fopen("arrivalTime1.dat", "wb");
FILE* arrivalTimeFile2 = fopen("arrivalTime2.dat", "wb");
short numPrint[MAX_NUM_CLIENTS];
memset(numPrint, 0, sizeof(short) * MAX_NUM_CLIENTS);
// Audio Buffers
short silence10ms[10 * 32];
memset(silence10ms, 0, 320 * sizeof(short));
short audioBuff10ms[10 * 32];
short audioBuff60ms[60 * 32];
short resampledAudio60ms[60 * 32];
unsigned short bitStream[600 + 600];
short speechType[1];
short numSampFreqChanged = 0;
while (numSampFreqChanged < 10) {
for (clientCntr = 0; clientCntr < NUM_CLIENTS; clientCntr++) {
// Encoding/decoding for this pair of clients, if there is
// audio for any of them
// if(audioLeft[clientCntr] || audioLeft[clientCntr + 1])
//{
// for(pairCntr = 0; pairCntr < 2; pairCntr++)
//{
senderIdx = clientCntr; // + pairCntr;
receiverIdx = 1 - clientCntr; // + (1 - pairCntr);
// if(num10ms[senderIdx] > 6)
//{
// printf("Too many frames read for client %d",
// senderIdx + 1);
// return -1;
//}
numSamplesRead =
(short)fread(audioBuff10ms, sizeof(short), samplesIn10ms[senderIdx],
inFile[senderIdx]);
if (numSamplesRead != samplesIn10ms[senderIdx]) {
// file finished switch encoder sampling frequency.
printf("Changing Encoder Sampling frequency in client %d to ",
senderIdx + 1);
fclose(inFile[senderIdx]);
numSampFreqChanged++;
if (encoderSampRate[senderIdx] == 16000) {
printf("super-wideband.\n");
OPEN_FILE_RB(inFile[senderIdx], fileNameSWB);
encoderSampRate[senderIdx] = 32000;
} else {
printf("wideband.\n");
OPEN_FILE_RB(inFile[senderIdx], fileNameWB);
encoderSampRate[senderIdx] = 16000;
}
WebRtcIsac_SetEncSampRate(codecInstance[senderIdx],
encoderSampRate[senderIdx]);
WebRtcIsac_SetDecSampRate(codecInstance[receiverIdx],
encoderSampRate[senderIdx]);
samplesIn10ms[clientCntr] = encoderSampRate[clientCntr] * 10;
numSamplesRead =
(short)fread(audioBuff10ms, sizeof(short), samplesIn10ms[senderIdx],
inFile[senderIdx]);
if (numSamplesRead != samplesIn10ms[senderIdx]) {
printf(" File %s for client %d has not enough audio\n",
(encoderSampRate[senderIdx] == 16000) ? "wideband"
: "super-wideband",
senderIdx + 1);
return -1;
}
}
num10ms[senderIdx]++;
// sanity check
// if(num10ms[senderIdx] > 6)
//{
// printf("Client %d has got more than 60 ms audio and encoded no
// packet.\n",
// senderIdx);
// return -1;
//}
// Encode
int streamLen_int = WebRtcIsac_Encode(codecInstance[senderIdx],
audioBuff10ms, (uint8_t*)bitStream);
int16_t ggg;
if (streamLen_int > 0) {
if ((WebRtcIsac_ReadFrameLen(
codecInstance[receiverIdx],
reinterpret_cast<const uint8_t*>(bitStream), &ggg)) < 0)
printf("ERROR\n");
}
// Sanity check
if (streamLen_int < 0) {
printf(" Encoder error in client %d \n", senderIdx + 1);
return -1;
}
streamLen = static_cast<size_t>(streamLen_int);
if (streamLen > 0) {
// Packet generated; model sending through a channel, do bandwidth
// estimation at the receiver and decode.
lenEncodedInBytes[senderIdx] += streamLen;
lenAudioIn10ms[senderIdx] += (unsigned int)num10ms[senderIdx];
lenEncodedInBytesTmp[senderIdx] += streamLen;
lenAudioIn10msTmp[senderIdx] += (unsigned int)num10ms[senderIdx];
// Print after ~5 sec.
if (lenAudioIn10msTmp[senderIdx] >= 100) {
numPrint[senderIdx]++;
printf(" %d, %6.3f => %6.3f ", senderIdx + 1,
bottleneck[senderIdx] / 1000.0,
lenEncodedInBytesTmp[senderIdx] * 0.8 /
lenAudioIn10msTmp[senderIdx]);
if (codingMode == 0) {
int32_t bn;
WebRtcIsac_GetUplinkBw(codecInstance[senderIdx], &bn);
printf("[%d] ", bn);
}
// int16_t rateIndexLB;
// int16_t rateIndexUB;
// WebRtcIsac_GetDownLinkBwIndex(codecInstance[receiverIdx],
// &rateIndexLB, &rateIndexUB);
// printf(" (%2d, %2d) ", rateIndexLB, rateIndexUB);
std::cout << std::flush;
lenEncodedInBytesTmp[senderIdx] = 0;
lenAudioIn10msTmp[senderIdx] = 0;
// if(senderIdx == (NUM_CLIENTS - 1))
//{
printf(" %0.1f \n", lenAudioIn10ms[senderIdx] * 10. / 1000);
//}
// After ~20 sec change the bottleneck.
// if((numPrint[senderIdx] == 4) && (codingMode == 0))
// {
// numPrint[senderIdx] = 0;
// if(codingMode == 0)
// {
// int newBottleneck = bottleneck[senderIdx] +
// (bottleneckChange[senderIdx] * 1000);
// if(bottleneckChange[senderIdx] > 0)
// {
// if(newBottleneck >maxBn)
// {
// bottleneckChange[senderIdx] = -1;
// newBottleneck = bottleneck[senderIdx] +
// (bottleneckChange[senderIdx] * 1000);
// if(newBottleneck > minBn)
// {
// bottleneck[senderIdx] = newBottleneck;
// }
// }
// else
// {
// bottleneck[senderIdx] = newBottleneck;
// }
// }
// else
// {
// if(newBottleneck < minBn)
// {
// bottleneckChange[senderIdx] = 1;
// newBottleneck = bottleneck[senderIdx] +
// (bottleneckChange[senderIdx] * 1000);
// if(newBottleneck < maxBn)
// {
// bottleneck[senderIdx] = newBottleneck;
// }
// }
// else
// {
// bottleneck[senderIdx] = newBottleneck;
// }
// }
// }
// }
}
// model a channel of given bottleneck, to get the receive timestamp
get_arrival_time(num10ms[senderIdx] * samplesIn10ms[senderIdx],
streamLen, bottleneck[senderIdx],
packetData[senderIdx],
encoderSampRate[senderIdx] * 1000,
encoderSampRate[senderIdx] * 1000);
// Write the arrival time.
if (senderIdx == 0) {
if (fwrite(&(packetData[senderIdx]->arrival_time),
sizeof(unsigned int), 1, arrivalTimeFile1) != 1) {
return -1;
}
} else {
if (fwrite(&(packetData[senderIdx]->arrival_time),
sizeof(unsigned int), 1, arrivalTimeFile2) != 1) {
return -1;
}
}
// BWE
if (WebRtcIsac_UpdateBwEstimate(
codecInstance[receiverIdx],
reinterpret_cast<const uint8_t*>(bitStream), streamLen,
packetData[senderIdx]->rtp_number,
packetData[senderIdx]->sample_count,
packetData[senderIdx]->arrival_time) < 0) {
printf(" BWE Error at client %d \n", receiverIdx + 1);
return -1;
}
/**/
// Decode
int lenDecodedAudio_int =
WebRtcIsac_Decode(codecInstance[receiverIdx],
reinterpret_cast<const uint8_t*>(bitStream),
streamLen, audioBuff60ms, speechType);
if (lenDecodedAudio_int < 0) {
printf(" Decoder error in client %d \n", receiverIdx + 1);
return -1;
}
lenDecodedAudio = static_cast<size_t>(lenDecodedAudio_int);
if (encoderSampRate[senderIdx] == 16000) {
WebRtcSpl_UpsampleBy2(audioBuff60ms, lenDecodedAudio,
resampledAudio60ms,
resamplerState[receiverIdx]);
if (fwrite(resampledAudio60ms, sizeof(short), lenDecodedAudio << 1,
outFile[receiverIdx]) != lenDecodedAudio << 1) {
return -1;
}
} else {
if (fwrite(audioBuff60ms, sizeof(short), lenDecodedAudio,
outFile[receiverIdx]) != lenDecodedAudio) {
return -1;
}
}
num10ms[senderIdx] = 0;
}
//}
//}
}
}
return 0;
}