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 "webrtc/modules/audio_coding/neteq/buffer_level_filter.h"
12 
13 #include <algorithm>  // Provide access to std::max.
14 
15 namespace webrtc {
16 
BufferLevelFilter()17 BufferLevelFilter::BufferLevelFilter() {
18   Reset();
19 }
20 
Reset()21 void BufferLevelFilter::Reset() {
22   filtered_current_level_ = 0;
23   level_factor_ = 253;
24 }
25 
Update(size_t buffer_size_packets,int time_stretched_samples,size_t packet_len_samples)26 void BufferLevelFilter::Update(size_t buffer_size_packets,
27                                int time_stretched_samples,
28                                size_t packet_len_samples) {
29   // Filter:
30   // |filtered_current_level_| = |level_factor_| * |filtered_current_level_| +
31   //                            (1 - |level_factor_|) * |buffer_size_packets|
32   // |level_factor_| and |filtered_current_level_| are in Q8.
33   // |buffer_size_packets| is in Q0.
34   filtered_current_level_ = ((level_factor_ * filtered_current_level_) >> 8) +
35       ((256 - level_factor_) * static_cast<int>(buffer_size_packets));
36 
37   // Account for time-scale operations (accelerate and pre-emptive expand).
38   if (time_stretched_samples && packet_len_samples > 0) {
39     // Time-scaling has been performed since last filter update. Subtract the
40     // value of |time_stretched_samples| from |filtered_current_level_| after
41     // converting |time_stretched_samples| from samples to packets in Q8.
42     // Make sure that the filtered value remains non-negative.
43     filtered_current_level_ = std::max(0,
44         filtered_current_level_ -
45         (time_stretched_samples << 8) / static_cast<int>(packet_len_samples));
46   }
47 }
48 
SetTargetBufferLevel(int target_buffer_level)49 void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level) {
50   if (target_buffer_level <= 1) {
51     level_factor_ = 251;
52   } else if (target_buffer_level <= 3) {
53     level_factor_ = 252;
54   } else if (target_buffer_level <= 7) {
55     level_factor_ = 253;
56   } else {
57     level_factor_ = 254;
58   }
59 }
60 
filtered_current_level() const61 int BufferLevelFilter::filtered_current_level() const {
62   return filtered_current_level_;
63 }
64 
65 }  // namespace webrtc
66