1 /* 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 11 #ifndef COMMON_AUDIO_SMOOTHING_FILTER_H_ 12 #define COMMON_AUDIO_SMOOTHING_FILTER_H_ 13 14 #include <stdint.h> 15 16 #include "absl/types/optional.h" 17 18 namespace webrtc { 19 20 class SmoothingFilter { 21 public: 22 virtual ~SmoothingFilter() = default; 23 virtual void AddSample(float sample) = 0; 24 virtual absl::optional<float> GetAverage() = 0; 25 virtual bool SetTimeConstantMs(int time_constant_ms) = 0; 26 }; 27 28 // SmoothingFilterImpl applies an exponential filter 29 // alpha = exp(-1.0 / time_constant_ms); 30 // y[t] = alpha * y[t-1] + (1 - alpha) * sample; 31 // 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. 34 class SmoothingFilterImpl final : public SmoothingFilter { 35 public: 36 // `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`. 43 explicit SmoothingFilterImpl(int init_time_ms); 44 45 SmoothingFilterImpl() = delete; 46 SmoothingFilterImpl(const SmoothingFilterImpl&) = delete; 47 SmoothingFilterImpl& operator=(const SmoothingFilterImpl&) = delete; 48 49 ~SmoothingFilterImpl() override; 50 51 void AddSample(float sample) override; 52 absl::optional<float> GetAverage() override; 53 bool SetTimeConstantMs(int time_constant_ms) override; 54 55 // Methods used for unittests. alpha()56 float alpha() const { return alpha_; } 57 58 private: 59 void UpdateAlpha(int time_constant_ms); 60 void ExtrapolateLastSample(int64_t time_ms); 61 62 const int init_time_ms_; 63 const float init_factor_; 64 const float init_const_; 65 66 absl::optional<int64_t> init_end_time_ms_; 67 float last_sample_; 68 float alpha_; 69 float state_; 70 int64_t last_state_time_ms_; 71 }; 72 73 } // namespace webrtc 74 75 #endif // COMMON_AUDIO_SMOOTHING_FILTER_H_ 76