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