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