Line data Source code
1 : /*
2 : * Copyright (c) 2015 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/common_audio/sparse_fir_filter.h"
12 :
13 : #include "webrtc/base/checks.h"
14 :
15 : namespace webrtc {
16 :
17 0 : SparseFIRFilter::SparseFIRFilter(const float* nonzero_coeffs,
18 : size_t num_nonzero_coeffs,
19 : size_t sparsity,
20 0 : size_t offset)
21 : : sparsity_(sparsity),
22 : offset_(offset),
23 0 : nonzero_coeffs_(nonzero_coeffs, nonzero_coeffs + num_nonzero_coeffs),
24 0 : state_(sparsity_ * (num_nonzero_coeffs - 1) + offset_, 0.f) {
25 0 : RTC_CHECK_GE(num_nonzero_coeffs, 1);
26 0 : RTC_CHECK_GE(sparsity, 1);
27 0 : }
28 :
29 : SparseFIRFilter::~SparseFIRFilter() = default;
30 :
31 0 : void SparseFIRFilter::Filter(const float* in, size_t length, float* out) {
32 : // Convolves the input signal |in| with the filter kernel |nonzero_coeffs_|
33 : // taking into account the previous state.
34 0 : for (size_t i = 0; i < length; ++i) {
35 0 : out[i] = 0.f;
36 : size_t j;
37 0 : for (j = 0; i >= j * sparsity_ + offset_ &&
38 0 : j < nonzero_coeffs_.size(); ++j) {
39 0 : out[i] += in[i - j * sparsity_ - offset_] * nonzero_coeffs_[j];
40 : }
41 0 : for (; j < nonzero_coeffs_.size(); ++j) {
42 0 : out[i] += state_[i + (nonzero_coeffs_.size() - j - 1) * sparsity_] *
43 0 : nonzero_coeffs_[j];
44 : }
45 : }
46 :
47 : // Update current state.
48 0 : if (state_.size() > 0u) {
49 0 : if (length >= state_.size()) {
50 0 : std::memcpy(&state_[0],
51 0 : &in[length - state_.size()],
52 0 : state_.size() * sizeof(*in));
53 : } else {
54 0 : std::memmove(&state_[0],
55 0 : &state_[length],
56 0 : (state_.size() - length) * sizeof(state_[0]));
57 0 : std::memcpy(&state_[state_.size() - length], in, length * sizeof(*in));
58 : }
59 : }
60 0 : }
61 :
62 : } // namespace webrtc
|