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