Home | History | Annotate | Download | only in common_audio
      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