blob: 0ebc7db0bb93e3c13054ffc25c7a68b8ce87030a [file] [log] [blame]
Per Åhgren38e2d952017-11-17 14:54:28 +01001/*
2 * Copyright (c) 2017 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#include "modules/audio_processing/aec3/decimator.h"
11
12#include "rtc_base/checks.h"
13
14namespace webrtc {
15namespace {
16
Gustaf Ullberg34c9f122018-06-07 07:55:01 +020017// signal.butter(2, 3400/8000.0, 'lowpass', analog=False)
18const std::vector<CascadedBiQuadFilter::BiQuadParam> kLowPassFilterDS2 = {
19 {{-1.f, 0.f}, {0.13833231f, 0.40743176f}, 0.22711796393486466f},
20 {{-1.f, 0.f}, {0.13833231f, 0.40743176f}, 0.22711796393486466f},
21 {{-1.f, 0.f}, {0.13833231f, 0.40743176f}, 0.22711796393486466f}};
Per Åhgren38e2d952017-11-17 14:54:28 +010022
Gustaf Ullberg34c9f122018-06-07 07:55:01 +020023// signal.butter(2, 750/8000.0, 'lowpass', analog=False)
24const std::vector<CascadedBiQuadFilter::BiQuadParam> kLowPassFilterDS4 = {
25 {{-1.f, 0.f}, {0.79396855f, 0.17030506f}, 0.017863192751682862f},
26 {{-1.f, 0.f}, {0.79396855f, 0.17030506f}, 0.017863192751682862f},
27 {{-1.f, 0.f}, {0.79396855f, 0.17030506f}, 0.017863192751682862f}};
Per Åhgren38e2d952017-11-17 14:54:28 +010028
Gustaf Ullberg34c9f122018-06-07 07:55:01 +020029// signal.cheby1(1, 6, [1000/8000, 2000/8000], btype='bandpass', analog=False)
30const std::vector<CascadedBiQuadFilter::BiQuadParam> kBandPassFilterDS8 = {
31 {{1.f, 0.f}, {0.7601815f, 0.46423542f}, 0.10330478266505948f, true},
32 {{1.f, 0.f}, {0.7601815f, 0.46423542f}, 0.10330478266505948f, true},
33 {{1.f, 0.f}, {0.7601815f, 0.46423542f}, 0.10330478266505948f, true},
34 {{1.f, 0.f}, {0.7601815f, 0.46423542f}, 0.10330478266505948f, true},
35 {{1.f, 0.f}, {0.7601815f, 0.46423542f}, 0.10330478266505948f, true}};
Per Åhgren38e2d952017-11-17 14:54:28 +010036
Gustaf Ullberg34c9f122018-06-07 07:55:01 +020037// signal.butter(2, 1000/8000.0, 'highpass', analog=False)
38const std::vector<CascadedBiQuadFilter::BiQuadParam> kHighPassFilter = {
39 {{1.f, 0.f}, {0.72712179f, 0.21296904f}, 0.7570763753338849f}};
Gustaf Ullberg6bf5a0d2018-05-18 15:45:09 +020040
Gustaf Ullberg34c9f122018-06-07 07:55:01 +020041const std::vector<CascadedBiQuadFilter::BiQuadParam> kPassThroughFilter = {};
Per Åhgren38e2d952017-11-17 14:54:28 +010042} // namespace
43
44Decimator::Decimator(size_t down_sampling_factor)
45 : down_sampling_factor_(down_sampling_factor),
Gustaf Ullberg34c9f122018-06-07 07:55:01 +020046 anti_aliasing_filter_(down_sampling_factor_ == 4
47 ? kLowPassFilterDS4
48 : (down_sampling_factor_ == 8
49 ? kBandPassFilterDS8
50 : kLowPassFilterDS2)),
51 noise_reduction_filter_(down_sampling_factor_ == 8 ? kPassThroughFilter
52 : kHighPassFilter) {
Per Åhgren38e2d952017-11-17 14:54:28 +010053 RTC_DCHECK(down_sampling_factor_ == 2 || down_sampling_factor_ == 4 ||
54 down_sampling_factor_ == 8);
55}
56
57void Decimator::Decimate(rtc::ArrayView<const float> in,
58 rtc::ArrayView<float> out) {
59 RTC_DCHECK_EQ(kBlockSize, in.size());
60 RTC_DCHECK_EQ(kBlockSize / down_sampling_factor_, out.size());
61 std::array<float, kBlockSize> x;
62
63 // Limit the frequency content of the signal to avoid aliasing.
Gustaf Ullberg78b1c4a2018-05-25 10:12:58 +020064 anti_aliasing_filter_.Process(in, x);
Per Åhgren38e2d952017-11-17 14:54:28 +010065
Gustaf Ullberg78b1c4a2018-05-25 10:12:58 +020066 // Reduce the impact of near-end noise.
67 noise_reduction_filter_.Process(x);
Gustaf Ullberg6bf5a0d2018-05-18 15:45:09 +020068
Per Åhgren38e2d952017-11-17 14:54:28 +010069 // Downsample the signal.
70 for (size_t j = 0, k = 0; j < out.size(); ++j, k += down_sampling_factor_) {
71 RTC_DCHECK_GT(kBlockSize, k);
72 out[j] = x[k];
73 }
74}
75
76} // namespace webrtc