xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/buffer_level_filter.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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<int64_t>(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, filtered_current_level - int64_t{time_stretched_samples} * (1 << 8)));
45 }
46 
SetFilteredBufferLevel(int buffer_size_samples)47 void BufferLevelFilter::SetFilteredBufferLevel(int buffer_size_samples) {
48   filtered_current_level_ =
49       rtc::saturated_cast<int>(int64_t{buffer_size_samples} * 256);
50 }
51 
SetTargetBufferLevel(int target_buffer_level_ms)52 void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level_ms) {
53   if (target_buffer_level_ms <= 20) {
54     level_factor_ = 251;
55   } else if (target_buffer_level_ms <= 60) {
56     level_factor_ = 252;
57   } else if (target_buffer_level_ms <= 140) {
58     level_factor_ = 253;
59   } else {
60     level_factor_ = 254;
61   }
62 }
63 
64 }  // namespace webrtc
65