downsample_fast.c (2481B)
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 "common_audio/signal_processing/include/signal_processing_library.h" 12 #include "rtc_base/checks.h" 13 #include "rtc_base/sanitizer.h" 14 15 // TODO(Bjornv): Change the function parameter order to WebRTC code style. 16 // C version of WebRtcSpl_DownsampleFast() for generic platforms. 17 int WebRtcSpl_DownsampleFastC(const int16_t* data_in, 18 size_t data_in_length, 19 int16_t* data_out, 20 size_t data_out_length, 21 const int16_t* __restrict coefficients, 22 size_t coefficients_length, 23 int factor, 24 size_t delay) { 25 int16_t* const original_data_out = data_out; 26 size_t i = 0; 27 size_t j = 0; 28 int32_t out_s32 = 0; 29 size_t endpos = delay + factor * (data_out_length - 1) + 1; 30 31 // Return error if any of the running conditions doesn't meet. 32 if (data_out_length == 0 || coefficients_length == 0 || 33 data_in_length < endpos) { 34 return -1; 35 } 36 37 rtc_MsanCheckInitialized(coefficients, sizeof(coefficients[0]), 38 coefficients_length); 39 40 for (i = delay; i < endpos; i += factor) { 41 out_s32 = 2048; // Round value, 0.5 in Q12. 42 43 for (j = 0; j < coefficients_length; j++) { 44 // Negative overflow is permitted here, because this is 45 // auto-regressive filters, and the state for each batch run is 46 // stored in the "negative" positions of the output vector. 47 rtc_MsanCheckInitialized(&data_in[(ptrdiff_t)i - (ptrdiff_t)j], 48 sizeof(data_in[0]), 1); 49 // out_s32 is in Q12 domain. 50 out_s32 += coefficients[j] * data_in[(ptrdiff_t)i - (ptrdiff_t)j]; 51 } 52 53 out_s32 >>= 12; // Q0. 54 55 // Saturate and store the output. 56 *data_out++ = WebRtcSpl_SatW32ToW16(out_s32); 57 } 58 59 RTC_DCHECK_EQ(original_data_out + data_out_length, data_out); 60 rtc_MsanCheckInitialized(original_data_out, sizeof(original_data_out[0]), 61 data_out_length); 62 63 return 0; 64 }