- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_processing / utility / delay_estimator_unittest.cc
1 /*
2  *  Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h"
12
13 extern "C" {
14 #include "webrtc/modules/audio_processing/utility/delay_estimator.h"
15 #include "webrtc/modules/audio_processing/utility/delay_estimator_internal.h"
16 #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h"
17 }
18 #include "webrtc/typedefs.h"
19
20 namespace {
21
22 enum { kSpectrumSize = 65 };
23 // Delay history sizes.
24 enum { kMaxDelay = 100 };
25 enum { kLookahead = 10 };
26 // Length of binary spectrum sequence.
27 enum { kSequenceLength = 400 };
28
29 class DelayEstimatorTest : public ::testing::Test {
30  protected:
31   DelayEstimatorTest();
32   virtual void SetUp();
33   virtual void TearDown();
34
35   void Init();
36   void InitBinary();
37   void VerifyDelay(BinaryDelayEstimator* binary_handle, int offset, int delay);
38   void RunBinarySpectra(BinaryDelayEstimator* binary1,
39                         BinaryDelayEstimator* binary2,
40                         int near_offset, int lookahead_offset, int far_offset);
41   void RunBinarySpectraTest(int near_offset, int lookahead_offset);
42
43   void* handle_;
44   DelayEstimator* self_;
45   void* farend_handle_;
46   DelayEstimatorFarend* farend_self_;
47   BinaryDelayEstimator* binary_;
48   BinaryDelayEstimatorFarend* binary_farend_;
49   int spectrum_size_;
50   // Dummy input spectra.
51   float far_f_[kSpectrumSize];
52   float near_f_[kSpectrumSize];
53   uint16_t far_u16_[kSpectrumSize];
54   uint16_t near_u16_[kSpectrumSize];
55   uint32_t binary_spectrum_[kSequenceLength + kMaxDelay + kLookahead];
56 };
57
58 DelayEstimatorTest::DelayEstimatorTest()
59     : handle_(NULL),
60       self_(NULL),
61       farend_handle_(NULL),
62       farend_self_(NULL),
63       binary_(NULL),
64       binary_farend_(NULL),
65       spectrum_size_(kSpectrumSize) {
66   // Dummy input data are set with more or less arbitrary non-zero values.
67   memset(far_f_, 1, sizeof(far_f_));
68   memset(near_f_, 2, sizeof(near_f_));
69   memset(far_u16_, 1, sizeof(far_u16_));
70   memset(near_u16_, 2, sizeof(near_u16_));
71   // Construct a sequence of binary spectra used to verify delay estimate. The
72   // |kSequenceLength| has to be long enough for the delay estimation to leave
73   // the initialized state.
74   binary_spectrum_[0] = 1;
75   for (int i = 1; i < (kSequenceLength + kMaxDelay + kLookahead); i++) {
76     binary_spectrum_[i] = 3 * binary_spectrum_[i - 1];
77   }
78 }
79
80 void DelayEstimatorTest::SetUp() {
81   farend_handle_ = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize,
82                                                      kMaxDelay + kLookahead);
83   ASSERT_TRUE(farend_handle_ != NULL);
84   farend_self_ = reinterpret_cast<DelayEstimatorFarend*>(farend_handle_);
85   handle_ = WebRtc_CreateDelayEstimator(farend_handle_, kLookahead);
86   ASSERT_TRUE(handle_ != NULL);
87   self_ = reinterpret_cast<DelayEstimator*>(handle_);
88   binary_farend_ = WebRtc_CreateBinaryDelayEstimatorFarend(kMaxDelay +
89                                                            kLookahead);
90   ASSERT_TRUE(binary_farend_ != NULL);
91   binary_ = WebRtc_CreateBinaryDelayEstimator(binary_farend_, kLookahead);
92   ASSERT_TRUE(binary_ != NULL);
93 }
94
95 void DelayEstimatorTest::TearDown() {
96   WebRtc_FreeDelayEstimator(handle_);
97   handle_ = NULL;
98   self_ = NULL;
99   WebRtc_FreeDelayEstimatorFarend(farend_handle_);
100   farend_handle_ = NULL;
101   farend_self_ = NULL;
102   WebRtc_FreeBinaryDelayEstimator(binary_);
103   binary_ = NULL;
104   WebRtc_FreeBinaryDelayEstimatorFarend(binary_farend_);
105   binary_farend_ = NULL;
106 }
107
108 void DelayEstimatorTest::Init() {
109   // Initialize Delay Estimator
110   EXPECT_EQ(0, WebRtc_InitDelayEstimatorFarend(farend_handle_));
111   EXPECT_EQ(0, WebRtc_InitDelayEstimator(handle_));
112   // Verify initialization.
113   EXPECT_EQ(0, farend_self_->far_spectrum_initialized);
114   EXPECT_EQ(0, self_->near_spectrum_initialized);
115   EXPECT_EQ(-2, WebRtc_last_delay(handle_));  // Delay in initial state.
116   EXPECT_EQ(0, WebRtc_last_delay_quality(handle_));  // Zero quality.
117 }
118
119 void DelayEstimatorTest::InitBinary() {
120   // Initialize Binary Delay Estimator (far-end part).
121   WebRtc_InitBinaryDelayEstimatorFarend(binary_farend_);
122   // Initialize Binary Delay Estimator
123   WebRtc_InitBinaryDelayEstimator(binary_);
124   // Verify initialization. This does not guarantee a complete check, since
125   // |last_delay| may be equal to -2 before initialization if done on the fly.
126   EXPECT_EQ(-2, binary_->last_delay);
127 }
128
129 void DelayEstimatorTest::VerifyDelay(BinaryDelayEstimator* binary_handle,
130                                      int offset, int delay) {
131   // Verify that we WebRtc_binary_last_delay() returns correct delay.
132   EXPECT_EQ(delay, WebRtc_binary_last_delay(binary_handle));
133
134   if (delay != -2) {
135     // Verify correct delay estimate. In the non-causal case the true delay
136     // is equivalent with the |offset|.
137     EXPECT_EQ(offset, delay);
138   }
139 }
140
141 void DelayEstimatorTest::RunBinarySpectra(BinaryDelayEstimator* binary1,
142                                           BinaryDelayEstimator* binary2,
143                                           int near_offset,
144                                           int lookahead_offset,
145                                           int far_offset) {
146   WebRtc_InitBinaryDelayEstimatorFarend(binary_farend_);
147   WebRtc_InitBinaryDelayEstimator(binary1);
148   WebRtc_InitBinaryDelayEstimator(binary2);
149   // Verify initialization. This does not guarantee a complete check, since
150   // |last_delay| may be equal to -2 before initialization if done on the fly.
151   EXPECT_EQ(-2, binary1->last_delay);
152   EXPECT_EQ(-2, binary2->last_delay);
153   for (int i = kLookahead; i < (kSequenceLength + kLookahead); i++) {
154     WebRtc_AddBinaryFarSpectrum(binary_farend_,
155                                 binary_spectrum_[i + far_offset]);
156     int delay_1 = WebRtc_ProcessBinarySpectrum(binary1, binary_spectrum_[i]);
157     int delay_2 =
158         WebRtc_ProcessBinarySpectrum(binary2,
159                                      binary_spectrum_[i - near_offset]);
160
161     VerifyDelay(binary1, far_offset + kLookahead, delay_1);
162     VerifyDelay(binary2,
163                 far_offset + kLookahead + lookahead_offset + near_offset,
164                 delay_2);
165     // Expect the two delay estimates to be offset by |lookahead_offset| +
166     // |near_offset| when we have left the initial state.
167     if ((delay_1 != -2) && (delay_2 != -2)) {
168       EXPECT_EQ(delay_1, delay_2 - lookahead_offset - near_offset);
169     }
170     if ((near_offset == 0) && (lookahead_offset == 0)) {
171       EXPECT_EQ(delay_1, delay_2);
172     }
173   }
174   // Verify that we have left the initialized state.
175   EXPECT_NE(-2, WebRtc_binary_last_delay(binary1));
176   EXPECT_NE(0, WebRtc_binary_last_delay_quality(binary1));
177   EXPECT_NE(-2, WebRtc_binary_last_delay(binary2));
178   EXPECT_NE(0, WebRtc_binary_last_delay_quality(binary2));
179 }
180
181 void DelayEstimatorTest::RunBinarySpectraTest(int near_offset,
182                                               int lookahead_offset) {
183   BinaryDelayEstimator* binary2 =
184       WebRtc_CreateBinaryDelayEstimator(binary_farend_,
185                                         kLookahead + lookahead_offset);
186   // Verify the delay for both causal and non-causal systems. For causal systems
187   // the delay is equivalent with a positive |offset| of the far-end sequence.
188   // For non-causal systems the delay is equivalent with a negative |offset| of
189   // the far-end sequence.
190   for (int offset = -kLookahead;
191       offset < kMaxDelay - lookahead_offset - near_offset;
192       offset++) {
193     RunBinarySpectra(binary_, binary2, near_offset, lookahead_offset, offset);
194   }
195   WebRtc_FreeBinaryDelayEstimator(binary2);
196   binary2 = NULL;
197 }
198
199 TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfWrapper) {
200   // In this test we verify correct error returns on invalid API calls.
201
202   // WebRtc_CreateDelayEstimatorFarend() and WebRtc_CreateDelayEstimator()
203   // should return a NULL pointer on invalid input values.
204   // Make sure we have a non-NULL value at start, so we can detect NULL after
205   // create failure.
206   void* handle = farend_handle_;
207   handle = WebRtc_CreateDelayEstimatorFarend(33, kMaxDelay + kLookahead);
208   EXPECT_TRUE(handle == NULL);
209   handle = farend_handle_;
210   handle = WebRtc_CreateDelayEstimatorFarend(kSpectrumSize, 1);
211   EXPECT_TRUE(handle == NULL);
212
213   handle = handle_;
214   handle = WebRtc_CreateDelayEstimator(NULL, kLookahead);
215   EXPECT_TRUE(handle == NULL);
216   handle = handle_;
217   handle = WebRtc_CreateDelayEstimator(farend_handle_, -1);
218   EXPECT_TRUE(handle == NULL);
219
220   // WebRtc_InitDelayEstimatorFarend() and WebRtc_InitDelayEstimator() should
221   // return -1 if we have a NULL pointer as |handle|.
222   EXPECT_EQ(-1, WebRtc_InitDelayEstimatorFarend(NULL));
223   EXPECT_EQ(-1, WebRtc_InitDelayEstimator(NULL));
224
225   // WebRtc_AddFarSpectrumFloat() should return -1 if we have:
226   // 1) NULL pointer as |handle|.
227   // 2) NULL pointer as far-end spectrum.
228   // 3) Incorrect spectrum size.
229   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFloat(NULL, far_f_, spectrum_size_));
230   // Use |farend_handle_| which is properly created at SetUp().
231   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFloat(farend_handle_, NULL,
232                                            spectrum_size_));
233   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFloat(farend_handle_, far_f_,
234                                            spectrum_size_ + 1));
235
236   // WebRtc_AddFarSpectrumFix() should return -1 if we have:
237   // 1) NULL pointer as |handle|.
238   // 2) NULL pointer as far-end spectrum.
239   // 3) Incorrect spectrum size.
240   // 4) Too high precision in far-end spectrum (Q-domain > 15).
241   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(NULL, far_u16_, spectrum_size_, 0));
242   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, NULL, spectrum_size_,
243                                          0));
244   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
245                                          spectrum_size_ + 1, 0));
246   EXPECT_EQ(-1, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
247                                          spectrum_size_, 16));
248
249   // WebRtc_DelayEstimatorProcessFloat() should return -1 if we have:
250   // 1) NULL pointer as |handle|.
251   // 2) NULL pointer as near-end spectrum.
252   // 3) Incorrect spectrum size.
253   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(NULL, near_f_,
254                                                   spectrum_size_));
255   // Use |handle_| which is properly created at SetUp().
256   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(handle_, NULL,
257                                                   spectrum_size_));
258   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFloat(handle_, near_f_,
259                                                   spectrum_size_ + 1));
260
261   // WebRtc_DelayEstimatorProcessFix() should return -1 if we have:
262   // 1) NULL pointer as |handle|.
263   // 3) NULL pointer as near-end spectrum.
264   // 4) Incorrect spectrum size.
265   // 6) Too high precision in near-end spectrum (Q-domain > 15).
266   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(NULL, near_u16_, spectrum_size_,
267                                                 0));
268   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, NULL, spectrum_size_,
269                                                 0));
270   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
271                                                 spectrum_size_ + 1, 0));
272   EXPECT_EQ(-1, WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
273                                                 spectrum_size_, 16));
274
275   // WebRtc_last_delay() should return -1 if we have a NULL pointer as |handle|.
276   EXPECT_EQ(-1, WebRtc_last_delay(NULL));
277
278   // WebRtc_last_delay_quality() should return -1 if we have a NULL pointer as
279   // |handle|.
280   EXPECT_EQ(-1, WebRtc_last_delay_quality(NULL));
281
282   // Free any local memory if needed.
283   WebRtc_FreeDelayEstimator(handle);
284 }
285
286 TEST_F(DelayEstimatorTest, InitializedSpectrumAfterProcess) {
287   // In this test we verify that the mean spectra are initialized after first
288   // time we call WebRtc_AddFarSpectrum() and Process() respectively.
289
290   // For floating point operations, process one frame and verify initialization
291   // flag.
292   Init();
293   EXPECT_EQ(0, WebRtc_AddFarSpectrumFloat(farend_handle_, far_f_,
294                                            spectrum_size_));
295   EXPECT_EQ(1, farend_self_->far_spectrum_initialized);
296   EXPECT_EQ(-2, WebRtc_DelayEstimatorProcessFloat(handle_, near_f_,
297                                                   spectrum_size_));
298   EXPECT_EQ(1, self_->near_spectrum_initialized);
299
300   // For fixed point operations, process one frame and verify initialization
301   // flag.
302   Init();
303   EXPECT_EQ(0, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
304                                          spectrum_size_, 0));
305   EXPECT_EQ(1, farend_self_->far_spectrum_initialized);
306   EXPECT_EQ(-2, WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
307                                                 spectrum_size_, 0));
308   EXPECT_EQ(1, self_->near_spectrum_initialized);
309 }
310
311 TEST_F(DelayEstimatorTest, CorrectLastDelay) {
312   // In this test we verify that we get the correct last delay upon valid call.
313   // We simply process the same data until we leave the initialized state
314   // (|last_delay| = -2). Then we compare the Process() output with the
315   // last_delay() call.
316
317   int last_delay = 0;
318   // Floating point operations.
319   Init();
320   for (int i = 0; i < 200; i++) {
321     EXPECT_EQ(0, WebRtc_AddFarSpectrumFloat(farend_handle_, far_f_,
322                                             spectrum_size_));
323     last_delay = WebRtc_DelayEstimatorProcessFloat(handle_, near_f_,
324                                                    spectrum_size_);
325     if (last_delay != -2) {
326       EXPECT_EQ(last_delay, WebRtc_last_delay(handle_));
327       EXPECT_EQ(7203, WebRtc_last_delay_quality(handle_));
328       break;
329     }
330   }
331   // Verify that we have left the initialized state.
332   EXPECT_NE(-2, WebRtc_last_delay(handle_));
333   EXPECT_NE(0, WebRtc_last_delay_quality(handle_));
334
335   // Fixed point operations.
336   Init();
337   for (int i = 0; i < 200; i++) {
338     EXPECT_EQ(0, WebRtc_AddFarSpectrumFix(farend_handle_, far_u16_,
339                                           spectrum_size_, 0));
340     last_delay = WebRtc_DelayEstimatorProcessFix(handle_, near_u16_,
341                                                  spectrum_size_, 0);
342     if (last_delay != -2) {
343       EXPECT_EQ(last_delay, WebRtc_last_delay(handle_));
344       EXPECT_EQ(7203, WebRtc_last_delay_quality(handle_));
345       break;
346     }
347   }
348   // Verify that we have left the initialized state.
349   EXPECT_NE(-2, WebRtc_last_delay(handle_));
350   EXPECT_NE(0, WebRtc_last_delay_quality(handle_));
351 }
352
353 TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimatorFarend) {
354   // In this test we verify correct output on invalid API calls to the Binary
355   // Delay Estimator (far-end part).
356
357   BinaryDelayEstimatorFarend* binary = binary_farend_;
358   // WebRtc_CreateBinaryDelayEstimatorFarend() should return -1 if the input
359   // history size is less than 2. This is to make sure the buffer shifting
360   // applies properly.
361   // Make sure we have a non-NULL value at start, so we can detect NULL after
362   // create failure.
363   binary = WebRtc_CreateBinaryDelayEstimatorFarend(1);
364   EXPECT_TRUE(binary == NULL);
365 }
366
367 TEST_F(DelayEstimatorTest, CorrectErrorReturnsOfBinaryEstimator) {
368   // In this test we verify correct output on invalid API calls to the Binary
369   // Delay Estimator.
370
371   BinaryDelayEstimator* binary_handle = binary_;
372   // WebRtc_CreateBinaryDelayEstimator() should return -1 if we have a NULL
373   // pointer as |binary_handle| or invalid input values. Upon failure, the
374   // |binary_handle| should be NULL.
375   // Make sure we have a non-NULL value at start, so we can detect NULL after
376   // create failure.
377   binary_handle = WebRtc_CreateBinaryDelayEstimator(NULL, kLookahead);
378   EXPECT_TRUE(binary_handle == NULL);
379   binary_handle = binary_;
380   binary_handle = WebRtc_CreateBinaryDelayEstimator(binary_farend_, -1);
381   EXPECT_TRUE(binary_handle == NULL);
382   binary_handle = binary_;
383   binary_handle = WebRtc_CreateBinaryDelayEstimator(0, 0);
384   EXPECT_TRUE(binary_handle == NULL);
385 }
386
387 TEST_F(DelayEstimatorTest, MeanEstimatorFix) {
388   // In this test we verify that we update the mean value in correct direction
389   // only. With "direction" we mean increase or decrease.
390
391   int32_t mean_value = 4000;
392   int32_t mean_value_before = mean_value;
393   int32_t new_mean_value = mean_value * 2;
394
395   // Increasing |mean_value|.
396   WebRtc_MeanEstimatorFix(new_mean_value, 10, &mean_value);
397   EXPECT_LT(mean_value_before, mean_value);
398   EXPECT_GT(new_mean_value, mean_value);
399
400   // Decreasing |mean_value|.
401   new_mean_value = mean_value / 2;
402   mean_value_before = mean_value;
403   WebRtc_MeanEstimatorFix(new_mean_value, 10, &mean_value);
404   EXPECT_GT(mean_value_before, mean_value);
405   EXPECT_LT(new_mean_value, mean_value);
406 }
407
408 TEST_F(DelayEstimatorTest, ExactDelayEstimateMultipleNearSameSpectrum) {
409   // In this test we verify that we get the correct delay estimates if we shift
410   // the signal accordingly. We create two Binary Delay Estimators and feed them
411   // with the same signals, so they should output the same results.
412   // We verify both causal and non-causal delays.
413
414   RunBinarySpectraTest(0, 0);
415 }
416
417 TEST_F(DelayEstimatorTest, ExactDelayEstimateMultipleNearDifferentSpectrum) {
418   // In this test we use the same setup as above, but we now feed the two Binary
419   // Delay Estimators with different signals, so they should output different
420   // results.
421
422   const int kNearOffset = 1;
423   RunBinarySpectraTest(kNearOffset, 0);
424 }
425
426 TEST_F(DelayEstimatorTest, ExactDelayEstimateMultipleNearDifferentLookahead) {
427   // In this test we use the same setup as above, feeding the two Binary
428   // Delay Estimators with the same signals. The difference is that we create
429   // them with different lookahead.
430
431   const int kLookaheadOffset = 1;
432   RunBinarySpectraTest(0, kLookaheadOffset);
433 }
434
435 }  // namespace