blob: e5f561ecf287f1a288e7db68202cbb3712a64a44 [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
Yves Gerey988cc082018-10-23 12:03:01 +020014#include <stdint.h>
15
Danil Chapovalov196100e2018-06-21 10:17:24 +020016#include "absl/types/optional.h"
Steve Anton10542f22019-01-11 09:11:00 -080017#include "rtc_base/constructor_magic.h"
minyue35483572016-09-20 23:13:08 -070018
19namespace webrtc {
20
21class SmoothingFilter {
22 public:
23 virtual ~SmoothingFilter() = default;
24 virtual void AddSample(float sample) = 0;
Danil Chapovalov196100e2018-06-21 10:17:24 +020025 virtual absl::optional<float> GetAverage() = 0;
minyue301fc4a2016-12-13 06:52:56 -080026 virtual bool SetTimeConstantMs(int time_constant_ms) = 0;
minyue35483572016-09-20 23:13:08 -070027};
28
29// SmoothingFilterImpl applies an exponential filter
minyue301fc4a2016-12-13 06:52:56 -080030// alpha = exp(-1.0 / time_constant_ms);
minyue35483572016-09-20 23:13:08 -070031// y[t] = alpha * y[t-1] + (1 - alpha) * sample;
minyue301fc4a2016-12-13 06:52:56 -080032// This implies a sample rate of 1000 Hz, i.e., 1 sample / ms.
33// But SmoothingFilterImpl allows sparse samples. All missing samples will be
34// assumed to equal the last received sample.
minyue35483572016-09-20 23:13:08 -070035class SmoothingFilterImpl final : public SmoothingFilter {
36 public:
minyue301fc4a2016-12-13 06:52:56 -080037 // |init_time_ms| is initialization time. It defines a period starting from
38 // the arriving time of the first sample. During this period, the exponential
39 // filter uses a varying time constant so that a smaller time constant will be
40 // applied to the earlier samples. This is to allow the the filter to adapt to
41 // earlier samples quickly. After the initialization period, the time constant
42 // will be set to |init_time_ms| first and can be changed through
43 // |SetTimeConstantMs|.
michaelt92aef172017-04-18 00:11:48 -070044 explicit SmoothingFilterImpl(int init_time_ms);
minyue301fc4a2016-12-13 06:52:56 -080045 ~SmoothingFilterImpl() override;
minyue35483572016-09-20 23:13:08 -070046
47 void AddSample(float sample) override;
Danil Chapovalov196100e2018-06-21 10:17:24 +020048 absl::optional<float> GetAverage() override;
minyue301fc4a2016-12-13 06:52:56 -080049 bool SetTimeConstantMs(int time_constant_ms) override;
50
51 // Methods used for unittests.
52 float alpha() const { return alpha_; }
minyue35483572016-09-20 23:13:08 -070053
54 private:
minyue301fc4a2016-12-13 06:52:56 -080055 void UpdateAlpha(int time_constant_ms);
56 void ExtrapolateLastSample(int64_t time_ms);
57
58 const int init_time_ms_;
59 const float init_factor_;
60 const float init_const_;
minyue35483572016-09-20 23:13:08 -070061
Danil Chapovalov196100e2018-06-21 10:17:24 +020062 absl::optional<int64_t> init_end_time_ms_;
minyue301fc4a2016-12-13 06:52:56 -080063 float last_sample_;
64 float alpha_;
65 float state_;
66 int64_t last_state_time_ms_;
minyue35483572016-09-20 23:13:08 -070067
minyue69b627d2016-11-24 11:01:09 -080068 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SmoothingFilterImpl);
minyue35483572016-09-20 23:13:08 -070069};
70
71} // namespace webrtc
72
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020073#endif // COMMON_AUDIO_SMOOTHING_FILTER_H_