1 /* 2 * Copyright (c) 2012 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/modules/audio_processing/vad/pole_zero_filter.h" 12 13 #include <stdlib.h> 14 #include <string.h> 15 #include <algorithm> 16 17 namespace webrtc { 18 19 PoleZeroFilter* PoleZeroFilter::Create(const float* numerator_coefficients, 20 size_t order_numerator, 21 const float* denominator_coefficients, 22 size_t order_denominator) { 23 if (order_numerator > kMaxFilterOrder || 24 order_denominator > kMaxFilterOrder || denominator_coefficients[0] == 0 || 25 numerator_coefficients == NULL || denominator_coefficients == NULL) 26 return NULL; 27 return new PoleZeroFilter(numerator_coefficients, order_numerator, 28 denominator_coefficients, order_denominator); 29 } 30 31 PoleZeroFilter::PoleZeroFilter(const float* numerator_coefficients, 32 size_t order_numerator, 33 const float* denominator_coefficients, 34 size_t order_denominator) 35 : past_input_(), 36 past_output_(), 37 numerator_coefficients_(), 38 denominator_coefficients_(), 39 order_numerator_(order_numerator), 40 order_denominator_(order_denominator), 41 highest_order_(std::max(order_denominator, order_numerator)) { 42 memcpy(numerator_coefficients_, numerator_coefficients, 43 sizeof(numerator_coefficients_[0]) * (order_numerator_ + 1)); 44 memcpy(denominator_coefficients_, denominator_coefficients, 45 sizeof(denominator_coefficients_[0]) * (order_denominator_ + 1)); 46 47 if (denominator_coefficients_[0] != 1) { 48 for (size_t n = 0; n <= order_numerator_; n++) 49 numerator_coefficients_[n] /= denominator_coefficients_[0]; 50 for (size_t n = 0; n <= order_denominator_; n++) 51 denominator_coefficients_[n] /= denominator_coefficients_[0]; 52 } 53 } 54 55 template <typename T> 56 static float FilterArPast(const T* past, size_t order, 57 const float* coefficients) { 58 float sum = 0.0f; 59 size_t past_index = order - 1; 60 for (size_t k = 1; k <= order; k++, past_index--) 61 sum += coefficients[k] * past[past_index]; 62 return sum; 63 } 64 65 int PoleZeroFilter::Filter(const int16_t* in, 66 size_t num_input_samples, 67 float* output) { 68 if (in == NULL || output == NULL) 69 return -1; 70 // This is the typical case, just a memcpy. 71 const size_t k = std::min(num_input_samples, highest_order_); 72 size_t n; 73 for (n = 0; n < k; n++) { 74 output[n] = in[n] * numerator_coefficients_[0]; 75 output[n] += FilterArPast(&past_input_[n], order_numerator_, 76 numerator_coefficients_); 77 output[n] -= FilterArPast(&past_output_[n], order_denominator_, 78 denominator_coefficients_); 79 80 past_input_[n + order_numerator_] = in[n]; 81 past_output_[n + order_denominator_] = output[n]; 82 } 83 if (highest_order_ < num_input_samples) { 84 for (size_t m = 0; n < num_input_samples; n++, m++) { 85 output[n] = in[n] * numerator_coefficients_[0]; 86 output[n] += 87 FilterArPast(&in[m], order_numerator_, numerator_coefficients_); 88 output[n] -= FilterArPast(&output[m], order_denominator_, 89 denominator_coefficients_); 90 } 91 // Record into the past signal. 92 memcpy(past_input_, &in[num_input_samples - order_numerator_], 93 sizeof(in[0]) * order_numerator_); 94 memcpy(past_output_, &output[num_input_samples - order_denominator_], 95 sizeof(output[0]) * order_denominator_); 96 } else { 97 // Odd case that the length of the input is shorter that filter order. 98 memmove(past_input_, &past_input_[num_input_samples], 99 order_numerator_ * sizeof(past_input_[0])); 100 memmove(past_output_, &past_output_[num_input_samples], 101 order_denominator_ * sizeof(past_output_[0])); 102 } 103 return 0; 104 } 105 106 } // namespace webrtc 107