1 /* 2 * Copyright (c) 2011 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 #include "utility.h" 12 13 #include <assert.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 18 #include "testing/gtest/include/gtest/gtest.h" 19 #include "webrtc/common.h" 20 #include "webrtc/common_types.h" 21 #include "webrtc/modules/audio_coding/include/audio_coding_module.h" 22 #include "webrtc/modules/audio_coding/acm2/acm_common_defs.h" 23 24 #define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13 25 26 namespace webrtc { 27 28 ACMTestTimer::ACMTestTimer() 29 : _msec(0), 30 _sec(0), 31 _min(0), 32 _hour(0) { 33 return; 34 } 35 36 ACMTestTimer::~ACMTestTimer() { 37 return; 38 } 39 40 void ACMTestTimer::Reset() { 41 _msec = 0; 42 _sec = 0; 43 _min = 0; 44 _hour = 0; 45 return; 46 } 47 void ACMTestTimer::Tick10ms() { 48 _msec += 10; 49 Adjust(); 50 return; 51 } 52 53 void ACMTestTimer::Tick1ms() { 54 _msec++; 55 Adjust(); 56 return; 57 } 58 59 void ACMTestTimer::Tick100ms() { 60 _msec += 100; 61 Adjust(); 62 return; 63 } 64 65 void ACMTestTimer::Tick1sec() { 66 _sec++; 67 Adjust(); 68 return; 69 } 70 71 void ACMTestTimer::CurrentTimeHMS(char* currTime) { 72 sprintf(currTime, "%4lu:%02u:%06.3f", _hour, _min, 73 (double) _sec + (double) _msec / 1000.); 74 return; 75 } 76 77 void ACMTestTimer::CurrentTime(unsigned long& h, unsigned char& m, 78 unsigned char& s, unsigned short& ms) { 79 h = _hour; 80 m = _min; 81 s = _sec; 82 ms = _msec; 83 return; 84 } 85 86 void ACMTestTimer::Adjust() { 87 unsigned int n; 88 if (_msec >= 1000) { 89 n = _msec / 1000; 90 _msec -= (1000 * n); 91 _sec += n; 92 } 93 if (_sec >= 60) { 94 n = _sec / 60; 95 _sec -= (n * 60); 96 _min += n; 97 } 98 if (_min >= 60) { 99 n = _min / 60; 100 _min -= (n * 60); 101 _hour += n; 102 } 103 } 104 105 int16_t ChooseCodec(CodecInst& codecInst) { 106 107 PrintCodecs(); 108 //AudioCodingModule* tmpACM = AudioCodingModule::Create(0); 109 uint8_t noCodec = AudioCodingModule::NumberOfCodecs(); 110 int8_t codecID; 111 bool outOfRange = false; 112 char myStr[15] = ""; 113 do { 114 printf("\nChoose a codec [0]: "); 115 EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL); 116 codecID = atoi(myStr); 117 if ((codecID < 0) || (codecID >= noCodec)) { 118 printf("\nOut of range.\n"); 119 outOfRange = true; 120 } 121 } while (outOfRange); 122 123 CHECK_ERROR(AudioCodingModule::Codec((uint8_t )codecID, &codecInst)); 124 return 0; 125 } 126 127 void PrintCodecs() { 128 uint8_t noCodec = AudioCodingModule::NumberOfCodecs(); 129 130 CodecInst codecInst; 131 printf("No Name [Hz] [bps]\n"); 132 for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) { 133 AudioCodingModule::Codec(codecCntr, &codecInst); 134 printf("%2d- %-18s %5d %6d\n", codecCntr, codecInst.plname, 135 codecInst.plfreq, codecInst.rate); 136 } 137 138 } 139 140 CircularBuffer::CircularBuffer(uint32_t len) 141 : _buff(NULL), 142 _idx(0), 143 _buffIsFull(false), 144 _calcAvg(false), 145 _calcVar(false), 146 _sum(0), 147 _sumSqr(0) { 148 _buff = new double[len]; 149 if (_buff == NULL) { 150 _buffLen = 0; 151 } else { 152 for (uint32_t n = 0; n < len; n++) { 153 _buff[n] = 0; 154 } 155 _buffLen = len; 156 } 157 } 158 159 CircularBuffer::~CircularBuffer() { 160 if (_buff != NULL) { 161 delete[] _buff; 162 _buff = NULL; 163 } 164 } 165 166 void CircularBuffer::Update(const double newVal) { 167 assert(_buffLen > 0); 168 169 // store the value that is going to be overwritten 170 double oldVal = _buff[_idx]; 171 // record the new value 172 _buff[_idx] = newVal; 173 // increment the index, to point to where we would 174 // write next 175 _idx++; 176 // it is a circular buffer, if we are at the end 177 // we have to cycle to the beginning 178 if (_idx >= _buffLen) { 179 // flag that the buffer is filled up. 180 _buffIsFull = true; 181 _idx = 0; 182 } 183 184 // Update 185 186 if (_calcAvg) { 187 // for the average we have to update 188 // the sum 189 _sum += (newVal - oldVal); 190 } 191 192 if (_calcVar) { 193 // to calculate variance we have to update 194 // the sum of squares 195 _sumSqr += (double) (newVal - oldVal) * (double) (newVal + oldVal); 196 } 197 } 198 199 void CircularBuffer::SetArithMean(bool enable) { 200 assert(_buffLen > 0); 201 202 if (enable && !_calcAvg) { 203 uint32_t lim; 204 if (_buffIsFull) { 205 lim = _buffLen; 206 } else { 207 lim = _idx; 208 } 209 _sum = 0; 210 for (uint32_t n = 0; n < lim; n++) { 211 _sum += _buff[n]; 212 } 213 } 214 _calcAvg = enable; 215 } 216 217 void CircularBuffer::SetVariance(bool enable) { 218 assert(_buffLen > 0); 219 220 if (enable && !_calcVar) { 221 uint32_t lim; 222 if (_buffIsFull) { 223 lim = _buffLen; 224 } else { 225 lim = _idx; 226 } 227 _sumSqr = 0; 228 for (uint32_t n = 0; n < lim; n++) { 229 _sumSqr += _buff[n] * _buff[n]; 230 } 231 } 232 _calcAvg = enable; 233 } 234 235 int16_t CircularBuffer::ArithMean(double& mean) { 236 assert(_buffLen > 0); 237 238 if (_buffIsFull) { 239 240 mean = _sum / (double) _buffLen; 241 return 0; 242 } else { 243 if (_idx > 0) { 244 mean = _sum / (double) _idx; 245 return 0; 246 } else { 247 return -1; 248 } 249 250 } 251 } 252 253 int16_t CircularBuffer::Variance(double& var) { 254 assert(_buffLen > 0); 255 256 if (_buffIsFull) { 257 var = _sumSqr / (double) _buffLen; 258 return 0; 259 } else { 260 if (_idx > 0) { 261 var = _sumSqr / (double) _idx; 262 return 0; 263 } else { 264 return -1; 265 } 266 } 267 } 268 269 bool FixedPayloadTypeCodec(const char* payloadName) { 270 char fixPayloadTypeCodecs[NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE][32] = { "PCMU", 271 "PCMA", "GSM", "G723", "DVI4", "LPC", "PCMA", "G722", "QCELP", "CN", 272 "MPA", "G728", "G729" }; 273 274 for (int n = 0; n < NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE; n++) { 275 if (!STR_CASE_CMP(payloadName, fixPayloadTypeCodecs[n])) { 276 return true; 277 } 278 } 279 return false; 280 } 281 282 void VADCallback::Reset() { 283 memset(_numFrameTypes, 0, sizeof(_numFrameTypes)); 284 } 285 286 VADCallback::VADCallback() { 287 memset(_numFrameTypes, 0, sizeof(_numFrameTypes)); 288 } 289 290 void VADCallback::PrintFrameTypes() { 291 printf("kEmptyFrame......... %d\n", _numFrameTypes[kEmptyFrame]); 292 printf("kAudioFrameSpeech... %d\n", _numFrameTypes[kAudioFrameSpeech]); 293 printf("kAudioFrameCN....... %d\n", _numFrameTypes[kAudioFrameCN]); 294 printf("kVideoFrameKey...... %d\n", _numFrameTypes[kVideoFrameKey]); 295 printf("kVideoFrameDelta.... %d\n", _numFrameTypes[kVideoFrameDelta]); 296 } 297 298 int32_t VADCallback::InFrameType(FrameType frame_type) { 299 _numFrameTypes[frame_type]++; 300 return 0; 301 } 302 303 } // namespace webrtc 304