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 "modules/audio_coding/neteq/buffer_level_filter.h"
12 
13 #include <stdint.h>
14 
15 #include <algorithm>
16 
17 #include "rtc_base/numerics/safe_conversions.h"
18 
19 namespace webrtc {
20 
BufferLevelFilter()21 BufferLevelFilter::BufferLevelFilter() {
22   Reset();
23 }
24 
Reset()25 void BufferLevelFilter::Reset() {
26   filtered_current_level_ = 0;
27   level_factor_ = 253;
28 }
29 
Update(size_t buffer_size_samples,int time_stretched_samples)30 void BufferLevelFilter::Update(size_t buffer_size_samples,
31                                int time_stretched_samples) {
32   // Filter:
33   // |filtered_current_level_| = |level_factor_| * |filtered_current_level_| +
34   //                            (1 - |level_factor_|) * |buffer_size_samples|
35   // |level_factor_| and |filtered_current_level_| are in Q8.
36   // |buffer_size_samples| is in Q0.
37   const int64_t filtered_current_level =
38       ((level_factor_ * int64_t{filtered_current_level_}) >> 8) +
39       ((256 - level_factor_) * rtc::dchecked_cast<int>(buffer_size_samples));
40 
41   // Account for time-scale operations (accelerate and pre-emptive expand) and
42   // make sure that the filtered value remains non-negative.
43   filtered_current_level_ = rtc::saturated_cast<int>(std::max<int64_t>(
44       0,
45       filtered_current_level - (int64_t{time_stretched_samples} * (1 << 8))));
46 }
47 
SetTargetBufferLevel(int target_buffer_level)48 void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level) {
49   if (target_buffer_level <= 1) {
50     level_factor_ = 251;
51   } else if (target_buffer_level <= 3) {
52     level_factor_ = 252;
53   } else if (target_buffer_level <= 7) {
54     level_factor_ = 253;
55   } else {
56     level_factor_ = 254;
57   }
58 }
59 
60 }  // namespace webrtc
61