blob: 83c25b537e45c18270cfc33e86947564257f3f5d [file] [log] [blame]
/*
* Copyright (c) 2011 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.
*/
#include "utility.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common_types.h" // NOLINT(build/include)
#include "modules/audio_coding/include/audio_coding_module.h"
#include "test/gtest.h"
#define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13
namespace webrtc {
ACMTestTimer::ACMTestTimer() : _msec(0), _sec(0), _min(0), _hour(0) {
return;
}
ACMTestTimer::~ACMTestTimer() {
return;
}
void ACMTestTimer::Reset() {
_msec = 0;
_sec = 0;
_min = 0;
_hour = 0;
return;
}
void ACMTestTimer::Tick10ms() {
_msec += 10;
Adjust();
return;
}
void ACMTestTimer::Tick1ms() {
_msec++;
Adjust();
return;
}
void ACMTestTimer::Tick100ms() {
_msec += 100;
Adjust();
return;
}
void ACMTestTimer::Tick1sec() {
_sec++;
Adjust();
return;
}
void ACMTestTimer::CurrentTimeHMS(char* currTime) {
sprintf(currTime, "%4lu:%02u:%06.3f", _hour, _min,
(double)_sec + (double)_msec / 1000.);
return;
}
void ACMTestTimer::CurrentTime(unsigned long& h,
unsigned char& m,
unsigned char& s,
unsigned short& ms) {
h = _hour;
m = _min;
s = _sec;
ms = _msec;
return;
}
void ACMTestTimer::Adjust() {
unsigned int n;
if (_msec >= 1000) {
n = _msec / 1000;
_msec -= (1000 * n);
_sec += n;
}
if (_sec >= 60) {
n = _sec / 60;
_sec -= (n * 60);
_min += n;
}
if (_min >= 60) {
n = _min / 60;
_min -= (n * 60);
_hour += n;
}
}
int16_t ChooseCodec(CodecInst& codecInst) {
PrintCodecs();
// AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
uint8_t noCodec = AudioCodingModule::NumberOfCodecs();
int8_t codecID;
bool outOfRange = false;
char myStr[15] = "";
do {
printf("\nChoose a codec [0]: ");
EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL);
codecID = atoi(myStr);
if ((codecID < 0) || (codecID >= noCodec)) {
printf("\nOut of range.\n");
outOfRange = true;
}
} while (outOfRange);
CHECK_ERROR(AudioCodingModule::Codec((uint8_t)codecID, &codecInst));
return 0;
}
void PrintCodecs() {
uint8_t noCodec = AudioCodingModule::NumberOfCodecs();
CodecInst codecInst;
printf("No Name [Hz] [bps]\n");
for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) {
AudioCodingModule::Codec(codecCntr, &codecInst);
printf("%2d- %-18s %5d %6d\n", codecCntr, codecInst.plname,
codecInst.plfreq, codecInst.rate);
}
}
namespace test {
CircularBuffer::CircularBuffer(uint32_t len)
: _buff(NULL),
_idx(0),
_buffIsFull(false),
_calcAvg(false),
_calcVar(false),
_sum(0),
_sumSqr(0) {
_buff = new double[len];
if (_buff == NULL) {
_buffLen = 0;
} else {
for (uint32_t n = 0; n < len; n++) {
_buff[n] = 0;
}
_buffLen = len;
}
}
CircularBuffer::~CircularBuffer() {
if (_buff != NULL) {
delete[] _buff;
_buff = NULL;
}
}
void CircularBuffer::Update(const double newVal) {
assert(_buffLen > 0);
// store the value that is going to be overwritten
double oldVal = _buff[_idx];
// record the new value
_buff[_idx] = newVal;
// increment the index, to point to where we would
// write next
_idx++;
// it is a circular buffer, if we are at the end
// we have to cycle to the beginning
if (_idx >= _buffLen) {
// flag that the buffer is filled up.
_buffIsFull = true;
_idx = 0;
}
// Update
if (_calcAvg) {
// for the average we have to update
// the sum
_sum += (newVal - oldVal);
}
if (_calcVar) {
// to calculate variance we have to update
// the sum of squares
_sumSqr += (double)(newVal - oldVal) * (double)(newVal + oldVal);
}
}
void CircularBuffer::SetArithMean(bool enable) {
assert(_buffLen > 0);
if (enable && !_calcAvg) {
uint32_t lim;
if (_buffIsFull) {
lim = _buffLen;
} else {
lim = _idx;
}
_sum = 0;
for (uint32_t n = 0; n < lim; n++) {
_sum += _buff[n];
}
}
_calcAvg = enable;
}
void CircularBuffer::SetVariance(bool enable) {
assert(_buffLen > 0);
if (enable && !_calcVar) {
uint32_t lim;
if (_buffIsFull) {
lim = _buffLen;
} else {
lim = _idx;
}
_sumSqr = 0;
for (uint32_t n = 0; n < lim; n++) {
_sumSqr += _buff[n] * _buff[n];
}
}
_calcAvg = enable;
}
int16_t CircularBuffer::ArithMean(double& mean) {
assert(_buffLen > 0);
if (_buffIsFull) {
mean = _sum / (double)_buffLen;
return 0;
} else {
if (_idx > 0) {
mean = _sum / (double)_idx;
return 0;
} else {
return -1;
}
}
}
int16_t CircularBuffer::Variance(double& var) {
assert(_buffLen > 0);
if (_buffIsFull) {
var = _sumSqr / (double)_buffLen;
return 0;
} else {
if (_idx > 0) {
var = _sumSqr / (double)_idx;
return 0;
} else {
return -1;
}
}
}
} // namespace test
bool FixedPayloadTypeCodec(const char* payloadName) {
char fixPayloadTypeCodecs[NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE][32] = {
"PCMU", "PCMA", "GSM", "G723", "DVI4", "LPC", "PCMA",
"G722", "QCELP", "CN", "MPA", "G728", "G729"};
for (int n = 0; n < NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE; n++) {
if (!STR_CASE_CMP(payloadName, fixPayloadTypeCodecs[n])) {
return true;
}
}
return false;
}
void VADCallback::Reset() {
memset(_numFrameTypes, 0, sizeof(_numFrameTypes));
}
VADCallback::VADCallback() {
memset(_numFrameTypes, 0, sizeof(_numFrameTypes));
}
void VADCallback::PrintFrameTypes() {
printf("kEmptyFrame......... %d\n", _numFrameTypes[kEmptyFrame]);
printf("kAudioFrameSpeech... %d\n", _numFrameTypes[kAudioFrameSpeech]);
printf("kAudioFrameCN....... %d\n", _numFrameTypes[kAudioFrameCN]);
printf("kVideoFrameKey...... %d\n", _numFrameTypes[kVideoFrameKey]);
printf("kVideoFrameDelta.... %d\n", _numFrameTypes[kVideoFrameDelta]);
}
int32_t VADCallback::InFrameType(FrameType frame_type) {
_numFrameTypes[frame_type]++;
return 0;
}
} // namespace webrtc