blob: cff746953aa80ad90cdd5d29e3d915171b35bf23 [file] [log] [blame]
minyue35483572016-09-20 23:13:08 -07001/*
2 * Copyright (c) 2016 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef COMMON_AUDIO_SMOOTHING_FILTER_H_
12#define COMMON_AUDIO_SMOOTHING_FILTER_H_
minyue35483572016-09-20 23:13:08 -070013
Danil Chapovalov196100e2018-06-21 10:17:24 +020014#include "absl/types/optional.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/constructormagic.h"
16#include "system_wrappers/include/clock.h"
minyue35483572016-09-20 23:13:08 -070017
18namespace webrtc {
19
20class SmoothingFilter {
21 public:
22 virtual ~SmoothingFilter() = default;
23 virtual void AddSample(float sample) = 0;
Danil Chapovalov196100e2018-06-21 10:17:24 +020024 virtual absl::optional<float> GetAverage() = 0;
minyue301fc4a2016-12-13 06:52:56 -080025 virtual bool SetTimeConstantMs(int time_constant_ms) = 0;
minyue35483572016-09-20 23:13:08 -070026};
27
28// SmoothingFilterImpl applies an exponential filter
minyue301fc4a2016-12-13 06:52:56 -080029// alpha = exp(-1.0 / time_constant_ms);
minyue35483572016-09-20 23:13:08 -070030// y[t] = alpha * y[t-1] + (1 - alpha) * sample;
minyue301fc4a2016-12-13 06:52:56 -080031// This implies a sample rate of 1000 Hz, i.e., 1 sample / ms.
32// But SmoothingFilterImpl allows sparse samples. All missing samples will be
33// assumed to equal the last received sample.
minyue35483572016-09-20 23:13:08 -070034class SmoothingFilterImpl final : public SmoothingFilter {
35 public:
minyue301fc4a2016-12-13 06:52:56 -080036 // |init_time_ms| is initialization time. It defines a period starting from
37 // the arriving time of the first sample. During this period, the exponential
38 // filter uses a varying time constant so that a smaller time constant will be
39 // applied to the earlier samples. This is to allow the the filter to adapt to
40 // earlier samples quickly. After the initialization period, the time constant
41 // will be set to |init_time_ms| first and can be changed through
42 // |SetTimeConstantMs|.
michaelt92aef172017-04-18 00:11:48 -070043 explicit SmoothingFilterImpl(int init_time_ms);
minyue301fc4a2016-12-13 06:52:56 -080044 ~SmoothingFilterImpl() override;
minyue35483572016-09-20 23:13:08 -070045
46 void AddSample(float sample) override;
Danil Chapovalov196100e2018-06-21 10:17:24 +020047 absl::optional<float> GetAverage() override;
minyue301fc4a2016-12-13 06:52:56 -080048 bool SetTimeConstantMs(int time_constant_ms) override;
49
50 // Methods used for unittests.
51 float alpha() const { return alpha_; }
minyue35483572016-09-20 23:13:08 -070052
53 private:
minyue301fc4a2016-12-13 06:52:56 -080054 void UpdateAlpha(int time_constant_ms);
55 void ExtrapolateLastSample(int64_t time_ms);
56
57 const int init_time_ms_;
58 const float init_factor_;
59 const float init_const_;
minyue35483572016-09-20 23:13:08 -070060
Danil Chapovalov196100e2018-06-21 10:17:24 +020061 absl::optional<int64_t> init_end_time_ms_;
minyue301fc4a2016-12-13 06:52:56 -080062 float last_sample_;
63 float alpha_;
64 float state_;
65 int64_t last_state_time_ms_;
minyue35483572016-09-20 23:13:08 -070066
minyue69b627d2016-11-24 11:01:09 -080067 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SmoothingFilterImpl);
minyue35483572016-09-20 23:13:08 -070068};
69
70} // namespace webrtc
71
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020072#endif // COMMON_AUDIO_SMOOTHING_FILTER_H_