blob: 948545d9488a6923491b6699c421c8c4219d385b [file] [log] [blame]
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "modules/audio_coding/neteq/buffer_level_filter.h"
#include <stdint.h>
#include <algorithm>
#include "rtc_base/numerics/safe_conversions.h"
namespace webrtc {
BufferLevelFilter::BufferLevelFilter() {
Reset();
}
void BufferLevelFilter::Reset() {
filtered_current_level_ = 0;
level_factor_ = 253;
}
void BufferLevelFilter::Update(size_t buffer_size_samples,
int time_stretched_samples) {
// Filter:
// `filtered_current_level_` = `level_factor_` * `filtered_current_level_` +
// (1 - `level_factor_`) * `buffer_size_samples`
// `level_factor_` and `filtered_current_level_` are in Q8.
// `buffer_size_samples` is in Q0.
const int64_t filtered_current_level =
(level_factor_* int64_t{filtered_current_level_} >> 8) +
(256 - level_factor_) * rtc::dchecked_cast<int64_t>(buffer_size_samples);
// Account for time-scale operations (accelerate and pre-emptive expand) and
// make sure that the filtered value remains non-negative.
filtered_current_level_ = rtc::saturated_cast<int>(std::max<int64_t>(
0, filtered_current_level - int64_t{time_stretched_samples} * (1 << 8)));
}
void BufferLevelFilter::SetFilteredBufferLevel(int buffer_size_samples) {
filtered_current_level_ =
rtc::saturated_cast<int>(int64_t{buffer_size_samples} * 256);
}
void BufferLevelFilter::SetTargetBufferLevel(int target_buffer_level_ms) {
if (target_buffer_level_ms <= 20) {
level_factor_ = 251;
} else if (target_buffer_level_ms <= 60) {
level_factor_ = 252;
} else if (target_buffer_level_ms <= 140) {
level_factor_ = 253;
} else {
level_factor_ = 254;
}
}
} // namespace webrtc