blob: 0c614819a82fcfaf10f7dfc1efbed7f6bf46b822 [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
niklase@google.com470e71d2011-07-07 08:21:25 +000017#include "audio_coding_module.h"
18#include "common_types.h"
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +000019#include "gtest/gtest.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
21#define NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE 13
22
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +000023namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000024
25ACMTestTimer::ACMTestTimer() :
26_msec(0),
27_sec(0),
28_min(0),
29_hour(0)
30{
31 return;
32}
33
34ACMTestTimer::~ACMTestTimer()
35{
36 return;
37}
38
39void ACMTestTimer::Reset()
40{
41 _msec = 0;
42 _sec = 0;
43 _min = 0;
44 _hour = 0;
45 return;
46}
47void ACMTestTimer::Tick10ms()
48{
49 _msec += 10;
50 Adjust();
51 return;
52}
53
54void ACMTestTimer::Tick1ms()
55{
56 _msec++;
57 Adjust();
58 return;
59}
60
61void ACMTestTimer::Tick100ms()
62{
63 _msec += 100;
64 Adjust();
65 return;
66}
67
68void ACMTestTimer::Tick1sec()
69{
70 _sec++;
71 Adjust();
72 return;
73}
74
75void ACMTestTimer::CurrentTimeHMS(char* currTime)
76{
77 sprintf(currTime, "%4lu:%02u:%06.3f", _hour, _min, (double)_sec + (double)_msec / 1000.);
78 return;
79}
80
81void ACMTestTimer::CurrentTime(
82 unsigned long& h,
83 unsigned char& m,
84 unsigned char& s,
85 unsigned short& ms)
86{
87 h = _hour;
88 m = _min;
89 s = _sec;
90 ms = _msec;
91 return;
92}
93
94void ACMTestTimer::Adjust()
95{
96 unsigned int n;
97 if(_msec >= 1000)
98 {
99 n = _msec / 1000;
100 _msec -= (1000 * n);
101 _sec += n;
102 }
103 if(_sec >= 60)
104 {
105 n = _sec / 60;
106 _sec -= (n * 60);
107 _min += n;
108 }
109 if(_min >= 60)
110 {
111 n = _min / 60;
112 _min -= (n * 60);
113 _hour += n;
114 }
115}
116
117
118WebRtc_Word16
119ChooseCodec(
120 CodecInst& codecInst)
121{
122
123 PrintCodecs();
124 //AudioCodingModule* tmpACM = AudioCodingModule::Create(0);
125 WebRtc_UWord8 noCodec = AudioCodingModule::NumberOfCodecs();
126 WebRtc_Word8 codecID;
127 bool outOfRange = false;
128 char myStr[15] = "";
129 do
130 {
131 printf("\nChoose a codec [0]: ");
kjellander@webrtc.org543c3ea2011-11-23 12:20:35 +0000132 EXPECT_TRUE(fgets(myStr, 10, stdin) != NULL);
niklase@google.com470e71d2011-07-07 08:21:25 +0000133 codecID = atoi(myStr);
134 if((codecID < 0) || (codecID >= noCodec))
135 {
136 printf("\nOut of range.\n");
137 outOfRange = true;
138 }
139 } while(outOfRange);
140
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000141 CHECK_ERROR(AudioCodingModule::Codec((WebRtc_UWord8)codecID, &codecInst));
niklase@google.com470e71d2011-07-07 08:21:25 +0000142 return 0;
143}
144
145void
146PrintCodecs()
147{
148 WebRtc_UWord8 noCodec = AudioCodingModule::NumberOfCodecs();
149
150 CodecInst codecInst;
151 printf("No Name [Hz] [bps]\n");
152 for(WebRtc_UWord8 codecCntr = 0; codecCntr < noCodec; codecCntr++)
153 {
tina.legrand@webrtc.org7a7a0082013-02-21 10:27:48 +0000154 AudioCodingModule::Codec(codecCntr, &codecInst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000155 printf("%2d- %-18s %5d %6d\n",
156 codecCntr, codecInst.plname, codecInst.plfreq, codecInst.rate);
157 }
158
159}
160
161CircularBuffer::CircularBuffer(WebRtc_UWord32 len):
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000162_buff(NULL),
163_idx(0),
niklase@google.com470e71d2011-07-07 08:21:25 +0000164_buffIsFull(false),
165_calcAvg(false),
166_calcVar(false),
167_sum(0),
tina.legrand@webrtc.org2e096922011-08-18 06:20:30 +0000168_sumSqr(0)
niklase@google.com470e71d2011-07-07 08:21:25 +0000169{
tina.legrand@webrtc.org5efcad12011-12-20 09:05:55 +0000170 _buff = new double[len];
niklase@google.com470e71d2011-07-07 08:21:25 +0000171 if(_buff == NULL)
172 {
173 _buffLen = 0;
174 }
175 else
176 {
177 for(WebRtc_UWord32 n = 0; n < len; n++)
178 {
179 _buff[n] = 0;
180 }
181 _buffLen = len;
182 }
183}
184
185CircularBuffer::~CircularBuffer()
186{
187 if(_buff != NULL)
188 {
189 delete [] _buff;
190 _buff = NULL;
191 }
192}
193
194void
195CircularBuffer::Update(
196 const double newVal)
197{
198 assert(_buffLen > 0);
199
200 // store the value that is going to be overwritten
201 double oldVal = _buff[_idx];
202 // record the new value
203 _buff[_idx] = newVal;
204 // increment the index, to point to where we would
205 // write next
206 _idx++;
207 // it is a circular buffer, if we are at the end
208 // we have to cycle to the beginning
209 if(_idx >= _buffLen)
210 {
211 // flag that the buffer is filled up.
212 _buffIsFull = true;
213 _idx = 0;
214 }
215
216 // Update
217
218 if(_calcAvg)
219 {
220 // for the average we have to update
221 // the sum
222 _sum += (newVal - oldVal);
223 }
224
225 if(_calcVar)
226 {
227 // to calculate variance we have to update
228 // the sum of squares
229 _sumSqr += (double)(newVal - oldVal) * (double)(newVal + oldVal);
230 }
231}
232
233void
234CircularBuffer::SetArithMean(
235 bool enable)
236{
237 assert(_buffLen > 0);
238
239 if(enable && !_calcAvg)
240 {
241 WebRtc_UWord32 lim;
242 if(_buffIsFull)
243 {
244 lim = _buffLen;
245 }
246 else
247 {
248 lim = _idx;
249 }
250 _sum = 0;
251 for(WebRtc_UWord32 n = 0; n < lim; n++)
252 {
253 _sum += _buff[n];
254 }
255 }
256 _calcAvg = enable;
257}
258
259void
260CircularBuffer::SetVariance(
261 bool enable)
262{
263 assert(_buffLen > 0);
264
265 if(enable && !_calcVar)
266 {
267 WebRtc_UWord32 lim;
268 if(_buffIsFull)
269 {
270 lim = _buffLen;
271 }
272 else
273 {
274 lim = _idx;
275 }
276 _sumSqr = 0;
277 for(WebRtc_UWord32 n = 0; n < lim; n++)
278 {
279 _sumSqr += _buff[n] * _buff[n];
280 }
281 }
282 _calcAvg = enable;
283}
284
285WebRtc_Word16
286CircularBuffer::ArithMean(double& mean)
287{
288 assert(_buffLen > 0);
289
290 if(_buffIsFull)
291 {
292
293 mean = _sum / (double)_buffLen;
294 return 0;
295 }
296 else
297 {
298 if(_idx > 0)
299 {
300 mean = _sum / (double)_idx;
301 return 0;
302 }
303 else
304 {
305 return -1;
306 }
307
308 }
309}
310
311WebRtc_Word16
312CircularBuffer::Variance(double& var)
313{
314 assert(_buffLen > 0);
315
316 if(_buffIsFull)
317 {
318 var = _sumSqr / (double)_buffLen;
319 return 0;
320 }
321 else
322 {
323 if(_idx > 0)
324 {
325 var = _sumSqr / (double)_idx;
326 return 0;
327 }
328 else
329 {
330 return -1;
331 }
332 }
333}
334
335
336
337bool
338FixedPayloadTypeCodec(const char* payloadName)
339{
340 char fixPayloadTypeCodecs[NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE][32] = {
341 "PCMU",
342 "PCMA",
343 "GSM",
344 "G723",
345 "DVI4",
346 "LPC",
347 "PCMA",
348 "G722",
349 "QCELP",
350 "CN",
351 "MPA",
352 "G728",
353 "G729"
354 };
355
356 for(int n = 0; n < NUM_CODECS_WITH_FIXED_PAYLOAD_TYPE; n++)
357 {
358 if(!STR_CASE_CMP(payloadName, fixPayloadTypeCodecs[n]))
359 {
360 return true;
361 }
362 }
363 return false;
364}
365
366DTMFDetector::DTMFDetector()
367{
368 for(WebRtc_Word16 n = 0; n < 1000; n++)
369 {
370 _toneCntr[n] = 0;
371 }
372}
373
374DTMFDetector::~DTMFDetector()
375{
376}
377
378WebRtc_Word32 DTMFDetector::IncomingDtmf(const WebRtc_UWord8 digitDtmf, const bool /* toneEnded */)
379{
380 fprintf(stdout, "%d-",digitDtmf);
381 _toneCntr[digitDtmf]++;
382 return 0;
383}
384
385void DTMFDetector::PrintDetectedDigits()
386{
387 for(WebRtc_Word16 n = 0; n < 1000; n++)
388 {
389 if(_toneCntr[n] > 0)
390 {
391 fprintf(stdout, "%d %u msec, \n", n, _toneCntr[n]*10);
392 }
393 }
394 fprintf(stdout, "\n");
395 return;
396}
397
398void
399VADCallback::Reset()
400{
401 for(int n = 0; n < 6; n++)
402 {
403 _numFrameTypes[n] = 0;
404 }
405}
406
407VADCallback::VADCallback()
408{
409 for(int n = 0; n < 6; n++)
410 {
411 _numFrameTypes[n] = 0;
412 }
413}
414
415void
416VADCallback::PrintFrameTypes()
417{
418 fprintf(stdout, "No encoding.................. %d\n", _numFrameTypes[0]);
419 fprintf(stdout, "Active normal encoded........ %d\n", _numFrameTypes[1]);
420 fprintf(stdout, "Passive normal encoded....... %d\n", _numFrameTypes[2]);
421 fprintf(stdout, "Passive DTX wideband......... %d\n", _numFrameTypes[3]);
422 fprintf(stdout, "Passive DTX narrowband....... %d\n", _numFrameTypes[4]);
423 fprintf(stdout, "Passive DTX super-wideband... %d\n", _numFrameTypes[5]);
424}
425
426WebRtc_Word32
427VADCallback::InFrameType(
428 WebRtc_Word16 frameType)
429{
430 _numFrameTypes[frameType]++;
431 return 0;
432}
tina.legrand@webrtc.org554ae1a2011-12-16 10:09:04 +0000433
434} // namespace webrtc