blob: 62594ea7ca1432332e48533c4b7757ff5331d045 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
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"
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000012
niklase@google.com470e71d2011-07-07 08:21:25 +000013#include <assert.h>
14#include <stdio.h>
15#include <stdlib.h>
16
tina.legrand@webrtc.org73222cf2013-03-15 13:29:17 +000017#include "testing/gtest/include/gtest/gtest.h"
18#include "webrtc/common_types.h"
19#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
20#include "webrtc/modules/audio_coding/main/source/acm_common_defs.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
22#define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13
23
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000024namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000025
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000026ACMTestTimer::ACMTestTimer()
27 : _msec(0),
28 _sec(0),
29 _min(0),
30 _hour(0) {
31 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000032}
33
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000034ACMTestTimer::~ACMTestTimer() {
35 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000036}
37
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000038void ACMTestTimer::Reset() {
39 _msec = 0;
40 _sec = 0;
41 _min = 0;
42 _hour = 0;
43 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000044}
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000045void ACMTestTimer::Tick10ms() {
46 _msec += 10;
47 Adjust();
48 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000049}
50
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000051void ACMTestTimer::Tick1ms() {
52 _msec++;
53 Adjust();
54 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000055}
56
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000057void ACMTestTimer::Tick100ms() {
58 _msec += 100;
59 Adjust();
60 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000061}
62
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000063void ACMTestTimer::Tick1sec() {
64 _sec++;
65 Adjust();
66 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000067}
68
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000069void ACMTestTimer::CurrentTimeHMS(char* currTime) {
70 sprintf(currTime, "%4lu:%02u:%06.3f", _hour, _min,
71 (double) _sec + (double) _msec / 1000.);
72 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000073}
74
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000075void ACMTestTimer::CurrentTime(unsigned long& h, unsigned char& m,
76 unsigned char& s, unsigned short& ms) {
77 h = _hour;
78 m = _min;
79 s = _sec;
80 ms = _msec;
81 return;
niklase@google.com470e71d2011-07-07 08:21:25 +000082}
83
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +000084void ACMTestTimer::Adjust() {
85 unsigned int n;
86 if (_msec >= 1000) {
87 n = _msec / 1000;
88 _msec -= (1000 * n);
89 _sec += n;
90 }
91 if (_sec >= 60) {
92 n = _sec / 60;
93 _sec -= (n * 60);
94 _min += n;
95 }
96 if (_min >= 60) {
97 n = _min / 60;
98 _min -= (n * 60);
99 _hour += n;
100 }
101}
102
103int16_t ChooseCodec(CodecInst& codecInst) {
104
105 PrintCodecs();
106 //AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
107 uint8_t noCodec = AudioCodingModule::NumberOfCodecs();
108 int8_t codecID;
109 bool outOfRange = false;
110 char myStr[15] = "";
111 do {
112 printf("\nChoose a codec [0]: ");
113 EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL);
114 codecID = atoi(myStr);
115 if ((codecID < 0) || (codecID >= noCodec)) {
116 printf("\nOut of range.\n");
117 outOfRange = true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000118 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000119 } while (outOfRange);
120
121 CHECK_ERROR(AudioCodingModule::Codec((uint8_t )codecID, &codecInst));
122 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000123}
124
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000125void PrintCodecs() {
126 uint8_t noCodec = AudioCodingModule::NumberOfCodecs();
niklase@google.com470e71d2011-07-07 08:21:25 +0000127
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000128 CodecInst codecInst;
129 printf("No Name [Hz] [bps]\n");
130 for (uint8_t codecCntr = 0; codecCntr < noCodec; codecCntr++) {
131 AudioCodingModule::Codec(codecCntr, &codecInst);
132 printf("%2d- %-18s %5d %6d\n", codecCntr, codecInst.plname,
133 codecInst.plfreq, codecInst.rate);
134 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000135
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000136}
niklase@google.com470e71d2011-07-07 08:21:25 +0000137
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000138CircularBuffer::CircularBuffer(uint32_t len)
139 : _buff(NULL),
140 _idx(0),
141 _buffIsFull(false),
142 _calcAvg(false),
143 _calcVar(false),
144 _sum(0),
145 _sumSqr(0) {
146 _buff = new double[len];
147 if (_buff == NULL) {
148 _buffLen = 0;
149 } else {
150 for (uint32_t n = 0; n < len; n++) {
151 _buff[n] = 0;
152 }
153 _buffLen = len;
154 }
155}
156
157CircularBuffer::~CircularBuffer() {
158 if (_buff != NULL) {
159 delete[] _buff;
160 _buff = NULL;
161 }
162}
163
164void CircularBuffer::Update(const double newVal) {
165 assert(_buffLen > 0);
166
167 // store the value that is going to be overwritten
168 double oldVal = _buff[_idx];
169 // record the new value
170 _buff[_idx] = newVal;
171 // increment the index, to point to where we would
172 // write next
173 _idx++;
174 // it is a circular buffer, if we are at the end
175 // we have to cycle to the beginning
176 if (_idx >= _buffLen) {
177 // flag that the buffer is filled up.
178 _buffIsFull = true;
179 _idx = 0;
180 }
181
182 // Update
183
184 if (_calcAvg) {
185 // for the average we have to update
186 // the sum
187 _sum += (newVal - oldVal);
188 }
189
190 if (_calcVar) {
191 // to calculate variance we have to update
192 // the sum of squares
193 _sumSqr += (double) (newVal - oldVal) * (double) (newVal + oldVal);
194 }
195}
196
197void CircularBuffer::SetArithMean(bool enable) {
198 assert(_buffLen > 0);
199
200 if (enable && !_calcAvg) {
201 uint32_t lim;
202 if (_buffIsFull) {
203 lim = _buffLen;
204 } else {
205 lim = _idx;
206 }
207 _sum = 0;
208 for (uint32_t n = 0; n < lim; n++) {
209 _sum += _buff[n];
210 }
211 }
212 _calcAvg = enable;
213}
214
215void CircularBuffer::SetVariance(bool enable) {
216 assert(_buffLen > 0);
217
218 if (enable && !_calcVar) {
219 uint32_t lim;
220 if (_buffIsFull) {
221 lim = _buffLen;
222 } else {
223 lim = _idx;
224 }
225 _sumSqr = 0;
226 for (uint32_t n = 0; n < lim; n++) {
227 _sumSqr += _buff[n] * _buff[n];
228 }
229 }
230 _calcAvg = enable;
231}
232
233int16_t CircularBuffer::ArithMean(double& mean) {
234 assert(_buffLen > 0);
235
236 if (_buffIsFull) {
237
238 mean = _sum / (double) _buffLen;
niklase@google.com470e71d2011-07-07 08:21:25 +0000239 return 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000240 } else {
241 if (_idx > 0) {
242 mean = _sum / (double) _idx;
243 return 0;
244 } else {
245 return -1;
246 }
247
248 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000249}
250
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000251int16_t CircularBuffer::Variance(double& var) {
252 assert(_buffLen > 0);
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000253
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000254 if (_buffIsFull) {
255 var = _sumSqr / (double) _buffLen;
niklase@google.com470e71d2011-07-07 08:21:25 +0000256 return 0;
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000257 } else {
258 if (_idx > 0) {
259 var = _sumSqr / (double) _idx;
260 return 0;
261 } else {
262 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000263 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000264 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000265}
266
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000267bool FixedPayloadTypeCodec(const char* payloadName) {
268 char fixPayloadTypeCodecs[NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE][32] = { "PCMU",
269 "PCMA", "GSM", "G723", "DVI4", "LPC", "PCMA", "G722", "QCELP", "CN",
270 "MPA", "G728", "G729" };
271
272 for (int n = 0; n < NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE; n++) {
273 if (!STR_CASE_CMP(payloadName, fixPayloadTypeCodecs[n])) {
274 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000275 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000276 }
277 return false;
niklase@google.com470e71d2011-07-07 08:21:25 +0000278}
279
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000280DTMFDetector::DTMFDetector() {
281 for (int16_t n = 0; n < 1000; n++) {
282 _toneCntr[n] = 0;
283 }
284}
285
286DTMFDetector::~DTMFDetector() {
287}
288
289int32_t DTMFDetector::IncomingDtmf(const uint8_t digitDtmf,
290 const bool /* toneEnded */) {
291 fprintf(stdout, "%d-", digitDtmf);
292 _toneCntr[digitDtmf]++;
293 return 0;
294}
295
296void DTMFDetector::PrintDetectedDigits() {
297 for (int16_t n = 0; n < 1000; n++) {
298 if (_toneCntr[n] > 0) {
299 fprintf(stdout, "%d %u msec, \n", n, _toneCntr[n] * 10);
niklase@google.com470e71d2011-07-07 08:21:25 +0000300 }
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000301 }
302 fprintf(stdout, "\n");
303 return;
niklase@google.com470e71d2011-07-07 08:21:25 +0000304}
305
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000306void VADCallback::Reset() {
307 for (int n = 0; n < 6; n++) {
308 _numFrameTypes[n] = 0;
309 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000310}
311
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000312VADCallback::VADCallback() {
313 for (int n = 0; n < 6; n++) {
314 _numFrameTypes[n] = 0;
315 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000316}
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +0000317
tina.legrand@webrtc.orgd5726a12013-05-03 07:34:12 +0000318void VADCallback::PrintFrameTypes() {
319 fprintf(stdout, "No encoding.................. %d\n", _numFrameTypes[0]);
320 fprintf(stdout, "Active normal encoded........ %d\n", _numFrameTypes[1]);
321 fprintf(stdout, "Passive normal encoded....... %d\n", _numFrameTypes[2]);
322 fprintf(stdout, "Passive DTX wideband......... %d\n", _numFrameTypes[3]);
323 fprintf(stdout, "Passive DTX narrowband....... %d\n", _numFrameTypes[4]);
324 fprintf(stdout, "Passive DTX super-wideband... %d\n", _numFrameTypes[5]);
325}
326
327int32_t VADCallback::InFrameType(int16_t frameType) {
328 _numFrameTypes[frameType]++;
329 return 0;
330}
331
332} // namespace webrtc