| /* | |
| * 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 |