1 /*
2 * Copyright (c) 2015 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 "modules/remote_bitrate_estimator/test/estimators/nada.h"
12
13 #include <algorithm>
14 #include <memory>
15 #include <numeric>
16
17 #include "modules/remote_bitrate_estimator/test/bwe_test_framework.h"
18 #include "modules/remote_bitrate_estimator/test/packet.h"
19 #include "modules/remote_bitrate_estimator/test/packet_sender.h"
20 #include "rtc_base/arraysize.h"
21 #include "rtc_base/constructormagic.h"
22 #include "test/gtest.h"
23 #include "test/testsupport/fileutils.h"
24
25 namespace webrtc {
26 namespace testing {
27 namespace bwe {
28
29 class FilterTest : public ::testing::Test {
30 public:
MedianFilterConstantArray()31 void MedianFilterConstantArray() {
32 std::fill_n(raw_signal_, kNumElements, kSignalValue);
33 for (int i = 0; i < kNumElements; ++i) {
34 int size = std::min(5, i + 1);
35 median_filtered_[i] =
36 NadaBweReceiver::MedianFilter(&raw_signal_[i + 1 - size], size);
37 }
38 }
39
MedianFilterIntermittentNoise()40 void MedianFilterIntermittentNoise() {
41 const int kValue = 500;
42 const int kNoise = 100;
43
44 for (int i = 0; i < kNumElements; ++i) {
45 raw_signal_[i] = kValue + kNoise * (i % 10 == 9 ? 1 : 0);
46 }
47 for (int i = 0; i < kNumElements; ++i) {
48 int size = std::min(5, i + 1);
49 median_filtered_[i] =
50 NadaBweReceiver::MedianFilter(&raw_signal_[i + 1 - size], size);
51 EXPECT_EQ(median_filtered_[i], kValue);
52 }
53 }
54
ExponentialSmoothingFilter(const int64_t raw_signal_[],int num_elements,int64_t exp_smoothed[])55 void ExponentialSmoothingFilter(const int64_t raw_signal_[],
56 int num_elements,
57 int64_t exp_smoothed[]) {
58 exp_smoothed[0] =
59 NadaBweReceiver::ExponentialSmoothingFilter(raw_signal_[0], -1, kAlpha);
60 for (int i = 1; i < num_elements; ++i) {
61 exp_smoothed[i] = NadaBweReceiver::ExponentialSmoothingFilter(
62 raw_signal_[i], exp_smoothed[i - 1], kAlpha);
63 }
64 }
65
ExponentialSmoothingConstantArray(int64_t exp_smoothed[])66 void ExponentialSmoothingConstantArray(int64_t exp_smoothed[]) {
67 std::fill_n(raw_signal_, kNumElements, kSignalValue);
68 ExponentialSmoothingFilter(raw_signal_, kNumElements, exp_smoothed);
69 }
70
71 protected:
72 static const int kNumElements = 1000;
73 static const int64_t kSignalValue;
74 static const float kAlpha;
75 int64_t raw_signal_[kNumElements];
76 int64_t median_filtered_[kNumElements];
77 };
78
79 const int64_t FilterTest::kSignalValue = 200;
80 const float FilterTest::kAlpha = 0.1f;
81
82 class TestBitrateObserver : public BitrateObserver {
83 public:
TestBitrateObserver()84 TestBitrateObserver()
85 : last_bitrate_(0), last_fraction_loss_(0), last_rtt_(0) {}
86
OnNetworkChanged(uint32_t bitrate,uint8_t fraction_loss,int64_t rtt)87 virtual void OnNetworkChanged(uint32_t bitrate,
88 uint8_t fraction_loss,
89 int64_t rtt) {
90 last_bitrate_ = bitrate;
91 last_fraction_loss_ = fraction_loss;
92 last_rtt_ = rtt;
93 }
94 uint32_t last_bitrate_;
95 uint8_t last_fraction_loss_;
96 int64_t last_rtt_;
97 };
98
99 class NadaSenderSideTest : public ::testing::Test {
100 public:
NadaSenderSideTest()101 NadaSenderSideTest()
102 : observer_(),
103 simulated_clock_(0),
104 nada_sender_(&observer_, &simulated_clock_) {}
~NadaSenderSideTest()105 ~NadaSenderSideTest() {}
106
107 private:
108 TestBitrateObserver observer_;
109 SimulatedClock simulated_clock_;
110
111 protected:
112 NadaBweSender nada_sender_;
113 };
114
115 class NadaReceiverSideTest : public ::testing::Test {
116 public:
NadaReceiverSideTest()117 NadaReceiverSideTest() : nada_receiver_(kFlowId) {}
~NadaReceiverSideTest()118 ~NadaReceiverSideTest() {}
119
120 protected:
121 const int kFlowId = 1; // Arbitrary.
122 NadaBweReceiver nada_receiver_;
123 };
124
125 class NadaFbGenerator {
126 public:
127 NadaFbGenerator();
128
NotCongestedFb(size_t receiving_rate,int64_t ref_signal_ms,int64_t send_time_ms)129 static NadaFeedback NotCongestedFb(size_t receiving_rate,
130 int64_t ref_signal_ms,
131 int64_t send_time_ms) {
132 int64_t exp_smoothed_delay_ms = ref_signal_ms;
133 int64_t est_queuing_delay_signal_ms = ref_signal_ms;
134 int64_t congestion_signal_ms = ref_signal_ms;
135 float derivative = 0.0f;
136 return NadaFeedback(kFlowId, kNowMs, exp_smoothed_delay_ms,
137 est_queuing_delay_signal_ms, congestion_signal_ms,
138 derivative, receiving_rate, send_time_ms);
139 }
140
CongestedFb(size_t receiving_rate,int64_t send_time_ms)141 static NadaFeedback CongestedFb(size_t receiving_rate, int64_t send_time_ms) {
142 int64_t exp_smoothed_delay_ms = 1000;
143 int64_t est_queuing_delay_signal_ms = 800;
144 int64_t congestion_signal_ms = 1000;
145 float derivative = 1.0f;
146 return NadaFeedback(kFlowId, kNowMs, exp_smoothed_delay_ms,
147 est_queuing_delay_signal_ms, congestion_signal_ms,
148 derivative, receiving_rate, send_time_ms);
149 }
150
ExtremelyCongestedFb(size_t receiving_rate,int64_t send_time_ms)151 static NadaFeedback ExtremelyCongestedFb(size_t receiving_rate,
152 int64_t send_time_ms) {
153 int64_t exp_smoothed_delay_ms = 100000;
154 int64_t est_queuing_delay_signal_ms = 0;
155 int64_t congestion_signal_ms = 100000;
156 float derivative = 10000.0f;
157 return NadaFeedback(kFlowId, kNowMs, exp_smoothed_delay_ms,
158 est_queuing_delay_signal_ms, congestion_signal_ms,
159 derivative, receiving_rate, send_time_ms);
160 }
161
162 private:
163 // Arbitrary values, won't change these test results.
164 static const int kFlowId = 2;
165 static const int64_t kNowMs = 1000;
166 };
167
168 // Verify if AcceleratedRampUp is called and that bitrate increases.
TEST_F(NadaSenderSideTest,AcceleratedRampUp)169 TEST_F(NadaSenderSideTest, AcceleratedRampUp) {
170 const int64_t kRefSignalMs = 1;
171 const int64_t kOneWayDelayMs = 50;
172 int original_bitrate = 2 * NadaBweSender::kMinNadaBitrateKbps;
173 size_t receiving_rate = static_cast<size_t>(original_bitrate);
174 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
175
176 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
177 receiving_rate, kRefSignalMs, send_time_ms);
178
179 nada_sender_.set_original_operating_mode(true);
180 nada_sender_.set_bitrate_kbps(original_bitrate);
181
182 // Trigger AcceleratedRampUp mode.
183 nada_sender_.GiveFeedback(not_congested_fb);
184 int bitrate_1_kbps = nada_sender_.bitrate_kbps();
185 EXPECT_GT(bitrate_1_kbps, original_bitrate);
186 // Updates the bitrate according to the receiving rate and other constant
187 // parameters.
188 nada_sender_.AcceleratedRampUp(not_congested_fb);
189 EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps);
190
191 nada_sender_.set_original_operating_mode(false);
192 nada_sender_.set_bitrate_kbps(original_bitrate);
193 // Trigger AcceleratedRampUp mode.
194 nada_sender_.GiveFeedback(not_congested_fb);
195 bitrate_1_kbps = nada_sender_.bitrate_kbps();
196 EXPECT_GT(bitrate_1_kbps, original_bitrate);
197 nada_sender_.AcceleratedRampUp(not_congested_fb);
198 EXPECT_EQ(nada_sender_.bitrate_kbps(), bitrate_1_kbps);
199 }
200
201 // Verify if AcceleratedRampDown is called and if bitrate decreases.
TEST_F(NadaSenderSideTest,AcceleratedRampDown)202 TEST_F(NadaSenderSideTest, AcceleratedRampDown) {
203 const int64_t kOneWayDelayMs = 50;
204 int original_bitrate = 3 * NadaBweSender::kMinNadaBitrateKbps;
205 size_t receiving_rate = static_cast<size_t>(original_bitrate);
206 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
207
208 NadaFeedback congested_fb =
209 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
210
211 nada_sender_.set_original_operating_mode(false);
212 nada_sender_.set_bitrate_kbps(original_bitrate);
213 nada_sender_.GiveFeedback(congested_fb); // Trigger AcceleratedRampDown mode.
214 int bitrate_1_kbps = nada_sender_.bitrate_kbps();
215 EXPECT_LE(bitrate_1_kbps, original_bitrate * 0.9f + 0.5f);
216 EXPECT_LT(bitrate_1_kbps, original_bitrate);
217
218 // Updates the bitrate according to the receiving rate and other constant
219 // parameters.
220 nada_sender_.AcceleratedRampDown(congested_fb);
221 int bitrate_2_kbps =
222 std::max(nada_sender_.bitrate_kbps(), NadaBweSender::kMinNadaBitrateKbps);
223 EXPECT_EQ(bitrate_2_kbps, bitrate_1_kbps);
224 }
225
TEST_F(NadaSenderSideTest,GradualRateUpdate)226 TEST_F(NadaSenderSideTest, GradualRateUpdate) {
227 const int64_t kDeltaSMs = 20;
228 const int64_t kRefSignalMs = 20;
229 const int64_t kOneWayDelayMs = 50;
230 int original_bitrate = 5 * NadaBweSender::kMinNadaBitrateKbps;
231 size_t receiving_rate = static_cast<size_t>(original_bitrate);
232 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
233
234 NadaFeedback congested_fb =
235 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
236 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
237 original_bitrate, kRefSignalMs, send_time_ms);
238
239 nada_sender_.set_bitrate_kbps(original_bitrate);
240 double smoothing_factor = 0.0;
241 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor);
242 EXPECT_EQ(nada_sender_.bitrate_kbps(), original_bitrate);
243
244 smoothing_factor = 1.0;
245 nada_sender_.GradualRateUpdate(congested_fb, kDeltaSMs, smoothing_factor);
246 EXPECT_LT(nada_sender_.bitrate_kbps(), original_bitrate);
247
248 nada_sender_.set_bitrate_kbps(original_bitrate);
249 nada_sender_.GradualRateUpdate(not_congested_fb, kDeltaSMs, smoothing_factor);
250 EXPECT_GT(nada_sender_.bitrate_kbps(), original_bitrate);
251 }
252
253 // Sending bitrate should decrease and reach its Min bound.
TEST_F(NadaSenderSideTest,VeryLowBandwith)254 TEST_F(NadaSenderSideTest, VeryLowBandwith) {
255 const int64_t kOneWayDelayMs = 50;
256
257 size_t receiving_rate =
258 static_cast<size_t>(NadaBweSender::kMinNadaBitrateKbps);
259 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
260
261 NadaFeedback extremely_congested_fb =
262 NadaFbGenerator::ExtremelyCongestedFb(receiving_rate, send_time_ms);
263 NadaFeedback congested_fb =
264 NadaFbGenerator::CongestedFb(receiving_rate, send_time_ms);
265
266 nada_sender_.set_bitrate_kbps(5 * NadaBweSender::kMinNadaBitrateKbps);
267 nada_sender_.set_original_operating_mode(true);
268 for (int i = 0; i < 100; ++i) {
269 // Trigger GradualRateUpdate mode.
270 nada_sender_.GiveFeedback(extremely_congested_fb);
271 }
272 // The original implementation doesn't allow the bitrate to stay at kMin,
273 // even if the congestion signal is very high.
274 EXPECT_GE(nada_sender_.bitrate_kbps(), NadaBweSender::kMinNadaBitrateKbps);
275
276 nada_sender_.set_original_operating_mode(false);
277 nada_sender_.set_bitrate_kbps(5 * NadaBweSender::kMinNadaBitrateKbps);
278
279 for (int i = 0; i < 1000; ++i) {
280 int previous_bitrate = nada_sender_.bitrate_kbps();
281 // Trigger AcceleratedRampDown mode.
282 nada_sender_.GiveFeedback(congested_fb);
283 EXPECT_LE(nada_sender_.bitrate_kbps(), previous_bitrate);
284 }
285 EXPECT_EQ(nada_sender_.bitrate_kbps(), NadaBweSender::kMinNadaBitrateKbps);
286 }
287
288 // Sending bitrate should increase and reach its Max bound.
TEST_F(NadaSenderSideTest,VeryHighBandwith)289 TEST_F(NadaSenderSideTest, VeryHighBandwith) {
290 const int64_t kOneWayDelayMs = 50;
291 const size_t kRecentReceivingRate = static_cast<size_t>(kMaxBitrateKbps);
292 const int64_t kRefSignalMs = 1;
293 int64_t send_time_ms = nada_sender_.NowMs() - kOneWayDelayMs;
294
295 NadaFeedback not_congested_fb = NadaFbGenerator::NotCongestedFb(
296 kRecentReceivingRate, kRefSignalMs, send_time_ms);
297
298 nada_sender_.set_original_operating_mode(true);
299 for (int i = 0; i < 100; ++i) {
300 int previous_bitrate = nada_sender_.bitrate_kbps();
301 nada_sender_.GiveFeedback(not_congested_fb);
302 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate);
303 }
304 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps);
305
306 nada_sender_.set_original_operating_mode(false);
307 nada_sender_.set_bitrate_kbps(NadaBweSender::kMinNadaBitrateKbps);
308
309 for (int i = 0; i < 100; ++i) {
310 int previous_bitrate = nada_sender_.bitrate_kbps();
311 nada_sender_.GiveFeedback(not_congested_fb);
312 EXPECT_GE(nada_sender_.bitrate_kbps(), previous_bitrate);
313 }
314 EXPECT_EQ(nada_sender_.bitrate_kbps(), kMaxBitrateKbps);
315 }
316
TEST_F(NadaReceiverSideTest,FeedbackInitialCases)317 TEST_F(NadaReceiverSideTest, FeedbackInitialCases) {
318 std::unique_ptr<NadaFeedback> nada_feedback(
319 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(0)));
320 EXPECT_EQ(nada_feedback, nullptr);
321
322 nada_feedback.reset(
323 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(100)));
324 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), -1);
325 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L);
326 EXPECT_EQ(nada_feedback->congestion_signal(), 0L);
327 EXPECT_EQ(nada_feedback->derivative(), 0.0f);
328 EXPECT_EQ(nada_feedback->receiving_rate(), 0.0f);
329 }
330
TEST_F(NadaReceiverSideTest,FeedbackEmptyQueues)331 TEST_F(NadaReceiverSideTest, FeedbackEmptyQueues) {
332 const int64_t kTimeGapMs = 50; // Between each packet.
333 const int64_t kOneWayDelayMs = 50;
334
335 // No added latency, delay = kOneWayDelayMs.
336 for (int i = 1; i < 10; ++i) {
337 int64_t send_time_us = i * kTimeGapMs * 1000;
338 int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs;
339 uint16_t sequence_number = static_cast<uint16_t>(i);
340 // Payload sizes are not important here.
341 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
342 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
343 }
344
345 // Baseline delay will be equal kOneWayDelayMs.
346 std::unique_ptr<NadaFeedback> nada_feedback(
347 static_cast<NadaFeedback*>(nada_receiver_.GetFeedback(500)));
348 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(), 0L);
349 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(), 0L);
350 EXPECT_EQ(nada_feedback->congestion_signal(), 0L);
351 EXPECT_EQ(nada_feedback->derivative(), 0.0f);
352 }
353
TEST_F(NadaReceiverSideTest,FeedbackIncreasingDelay)354 TEST_F(NadaReceiverSideTest, FeedbackIncreasingDelay) {
355 // Since packets are 100ms apart, each one corresponds to a feedback.
356 const int64_t kTimeGapMs = 100; // Between each packet.
357
358 // Raw delays are = [10 20 30 40 50 60 70 80] ms.
359 // Baseline delay will be 50 ms.
360 // Delay signals should be: [0 10 20 30 40 50 60 70] ms.
361 const int64_t kMedianFilteredDelaysMs[] = {0, 5, 10, 15, 20, 30, 40, 50};
362 const int kNumPackets = arraysize(kMedianFilteredDelaysMs);
363 const float kAlpha = 0.1f; // Used for exponential smoothing.
364
365 int64_t exp_smoothed_delays_ms[kNumPackets];
366 exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0];
367
368 for (int i = 1; i < kNumPackets; ++i) {
369 exp_smoothed_delays_ms[i] = static_cast<int64_t>(
370 kAlpha * kMedianFilteredDelaysMs[i] +
371 (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f);
372 }
373
374 for (int i = 0; i < kNumPackets; ++i) {
375 int64_t send_time_us = (i + 1) * kTimeGapMs * 1000;
376 int64_t arrival_time_ms = send_time_us / 1000 + 10 * (i + 1);
377 uint16_t sequence_number = static_cast<uint16_t>(i + 1);
378 // Payload sizes are not important here.
379 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
380 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
381
382 std::unique_ptr<NadaFeedback> nada_feedback(static_cast<NadaFeedback*>(
383 nada_receiver_.GetFeedback(arrival_time_ms)));
384 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(),
385 exp_smoothed_delays_ms[i]);
386 // Since delay signals are lower than 50ms, they will not be non-linearly
387 // warped.
388 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(),
389 exp_smoothed_delays_ms[i]);
390 // Zero loss, congestion signal = queuing_delay
391 EXPECT_EQ(nada_feedback->congestion_signal(), exp_smoothed_delays_ms[i]);
392 if (i == 0) {
393 EXPECT_NEAR(nada_feedback->derivative(),
394 static_cast<float>(exp_smoothed_delays_ms[i]) / kTimeGapMs,
395 0.005f);
396 } else {
397 EXPECT_NEAR(nada_feedback->derivative(),
398 static_cast<float>(exp_smoothed_delays_ms[i] -
399 exp_smoothed_delays_ms[i - 1]) /
400 kTimeGapMs,
401 0.005f);
402 }
403 }
404 }
405
Warp(int64_t input)406 int64_t Warp(int64_t input) {
407 const int64_t kMinThreshold = 50; // Referred as d_th.
408 const int64_t kMaxThreshold = 400; // Referred as d_max.
409 if (input < kMinThreshold) {
410 return input;
411 } else if (input < kMaxThreshold) {
412 return static_cast<int64_t>(
413 pow((static_cast<double>(kMaxThreshold - input)) /
414 (kMaxThreshold - kMinThreshold),
415 4.0) *
416 kMinThreshold);
417 } else {
418 return 0L;
419 }
420 }
421
TEST_F(NadaReceiverSideTest,FeedbackWarpedDelay)422 TEST_F(NadaReceiverSideTest, FeedbackWarpedDelay) {
423 // Since packets are 100ms apart, each one corresponds to a feedback.
424 const int64_t kTimeGapMs = 100; // Between each packet.
425
426 // Raw delays are = [50 250 450 650 850 1050 1250 1450] ms.
427 // Baseline delay will be 50 ms.
428 // Delay signals should be: [0 200 400 600 800 1000 1200 1400] ms.
429 const int64_t kMedianFilteredDelaysMs[] = {
430 0, 100, 200, 300, 400, 600, 800, 1000};
431 const int kNumPackets = arraysize(kMedianFilteredDelaysMs);
432 const float kAlpha = 0.1f; // Used for exponential smoothing.
433
434 int64_t exp_smoothed_delays_ms[kNumPackets];
435 exp_smoothed_delays_ms[0] = kMedianFilteredDelaysMs[0];
436
437 for (int i = 1; i < kNumPackets; ++i) {
438 exp_smoothed_delays_ms[i] = static_cast<int64_t>(
439 kAlpha * kMedianFilteredDelaysMs[i] +
440 (1.0f - kAlpha) * exp_smoothed_delays_ms[i - 1] + 0.5f);
441 }
442
443 for (int i = 0; i < kNumPackets; ++i) {
444 int64_t send_time_us = (i + 1) * kTimeGapMs * 1000;
445 int64_t arrival_time_ms = send_time_us / 1000 + 50 + 200 * i;
446 uint16_t sequence_number = static_cast<uint16_t>(i + 1);
447 // Payload sizes are not important here.
448 const MediaPacket media_packet(kFlowId, send_time_us, 0, sequence_number);
449 nada_receiver_.ReceivePacket(arrival_time_ms, media_packet);
450
451 std::unique_ptr<NadaFeedback> nada_feedback(static_cast<NadaFeedback*>(
452 nada_receiver_.GetFeedback(arrival_time_ms)));
453 EXPECT_EQ(nada_feedback->exp_smoothed_delay_ms(),
454 exp_smoothed_delays_ms[i]);
455 // Delays can be non-linearly warped.
456 EXPECT_EQ(nada_feedback->est_queuing_delay_signal_ms(),
457 Warp(exp_smoothed_delays_ms[i]));
458 // Zero loss, congestion signal = queuing_delay
459 EXPECT_EQ(nada_feedback->congestion_signal(),
460 Warp(exp_smoothed_delays_ms[i]));
461 }
462 }
463
TEST_F(FilterTest,MedianConstantArray)464 TEST_F(FilterTest, MedianConstantArray) {
465 MedianFilterConstantArray();
466 for (int i = 0; i < kNumElements; ++i) {
467 EXPECT_EQ(median_filtered_[i], raw_signal_[i]);
468 }
469 }
470
TEST_F(FilterTest,MedianIntermittentNoise)471 TEST_F(FilterTest, MedianIntermittentNoise) {
472 MedianFilterIntermittentNoise();
473 }
474
TEST_F(FilterTest,ExponentialSmoothingConstantArray)475 TEST_F(FilterTest, ExponentialSmoothingConstantArray) {
476 int64_t exp_smoothed[kNumElements];
477 ExponentialSmoothingConstantArray(exp_smoothed);
478 for (int i = 0; i < kNumElements; ++i) {
479 EXPECT_EQ(exp_smoothed[i], kSignalValue);
480 }
481 }
482
TEST_F(FilterTest,ExponentialSmoothingInitialPertubation)483 TEST_F(FilterTest, ExponentialSmoothingInitialPertubation) {
484 const int64_t kSignal[] = {90000, 0, 0, 0, 0, 0};
485 const int kNumElements = arraysize(kSignal);
486 int64_t exp_smoothed[kNumElements];
487 ExponentialSmoothingFilter(kSignal, kNumElements, exp_smoothed);
488 for (int i = 1; i < kNumElements; ++i) {
489 EXPECT_EQ(
490 exp_smoothed[i],
491 static_cast<int64_t>(exp_smoothed[i - 1] * (1.0f - kAlpha) + 0.5f));
492 }
493 }
494
495 } // namespace bwe
496 } // namespace testing
497 } // namespace webrtc
498