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