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
15namespace webrtc {
16
17BufferLevelFilter::BufferLevelFilter() {
18  Reset();
19}
20
21void BufferLevelFilter::Reset() {
22  filtered_current_level_ = 0;
23  level_factor_ = 253;
24}
25
26void BufferLevelFilter::Update(int buffer_size_packets,
27                               int time_stretched_samples,
28                               int 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_) * 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) / packet_len_samples);
46  }
47}
48
49void 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}  // namespace webrtc
61