Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Side by Side Diff: webrtc/common_audio/resampler/sinc_resampler.cc

Issue 2535643002: Replace some asserts with DCHECKs (Closed)
Patch Set: Don't use the enum hack Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/common_audio/fir_filter_sse.cc ('k') | webrtc/common_types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 // 8) Else, if we're not on the second load, goto (4). 80 // 8) Else, if we're not on the second load, goto (4).
81 // 81 //
82 // Note: we're glossing over how the sub-sample handling works with 82 // Note: we're glossing over how the sub-sample handling works with
83 // |virtual_source_idx_|, etc. 83 // |virtual_source_idx_|, etc.
84 84
85 // MSVC++ requires this to be set before any other includes to get M_PI. 85 // MSVC++ requires this to be set before any other includes to get M_PI.
86 #define _USE_MATH_DEFINES 86 #define _USE_MATH_DEFINES
87 87
88 #include "webrtc/common_audio/resampler/sinc_resampler.h" 88 #include "webrtc/common_audio/resampler/sinc_resampler.h"
89 89
90 #include <assert.h>
91 #include <math.h> 90 #include <math.h>
92 #include <string.h> 91 #include <string.h>
93 92
94 #include <limits> 93 #include <limits>
95 94
95 #include "webrtc/base/checks.h"
96 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" 96 #include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
97 #include "webrtc/typedefs.h" 97 #include "webrtc/typedefs.h"
98 98
99 namespace webrtc { 99 namespace webrtc {
100 100
101 namespace { 101 namespace {
102 102
103 double SincScaleFactor(double io_ratio) { 103 double SincScaleFactor(double io_ratio) {
104 // |sinc_scale_factor| is basically the normalized cutoff frequency of the 104 // |sinc_scale_factor| is basically the normalized cutoff frequency of the
105 // low-pass filter. 105 // low-pass filter.
106 double sinc_scale_factor = io_ratio > 1.0 ? 1.0 / io_ratio : 1.0; 106 double sinc_scale_factor = io_ratio > 1.0 ? 1.0 / io_ratio : 1.0;
107 107
108 // The sinc function is an idealized brick-wall filter, but since we're 108 // The sinc function is an idealized brick-wall filter, but since we're
109 // windowing it the transition from pass to stop does not happen right away. 109 // windowing it the transition from pass to stop does not happen right away.
110 // So we should adjust the low pass filter cutoff slightly downward to avoid 110 // So we should adjust the low pass filter cutoff slightly downward to avoid
111 // some aliasing at the very high-end. 111 // some aliasing at the very high-end.
112 // TODO(crogers): this value is empirical and to be more exact should vary 112 // TODO(crogers): this value is empirical and to be more exact should vary
113 // depending on kKernelSize. 113 // depending on kKernelSize.
114 sinc_scale_factor *= 0.9; 114 sinc_scale_factor *= 0.9;
115 115
116 return sinc_scale_factor; 116 return sinc_scale_factor;
117 } 117 }
118 118
119 } // namespace 119 } // namespace
120 120
121 const size_t SincResampler::kKernelSize;
122
121 // If we know the minimum architecture at compile time, avoid CPU detection. 123 // If we know the minimum architecture at compile time, avoid CPU detection.
122 #if defined(WEBRTC_ARCH_X86_FAMILY) 124 #if defined(WEBRTC_ARCH_X86_FAMILY)
123 #if defined(__SSE2__) 125 #if defined(__SSE2__)
124 #define CONVOLVE_FUNC Convolve_SSE 126 #define CONVOLVE_FUNC Convolve_SSE
125 void SincResampler::InitializeCPUSpecificFeatures() {} 127 void SincResampler::InitializeCPUSpecificFeatures() {}
126 #else 128 #else
127 // x86 CPU detection required. Function will be set by 129 // x86 CPU detection required. Function will be set by
128 // InitializeCPUSpecificFeatures(). 130 // InitializeCPUSpecificFeatures().
129 // TODO(dalecurtis): Once Chrome moves to an SSE baseline this can be removed. 131 // TODO(dalecurtis): Once Chrome moves to an SSE baseline this can be removed.
130 #define CONVOLVE_FUNC convolve_proc_ 132 #define CONVOLVE_FUNC convolve_proc_
(...skipping 27 matching lines...) Expand all
158 AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))), 160 AlignedMalloc(sizeof(float) * kKernelStorageSize, 16))),
159 input_buffer_(static_cast<float*>( 161 input_buffer_(static_cast<float*>(
160 AlignedMalloc(sizeof(float) * input_buffer_size_, 16))), 162 AlignedMalloc(sizeof(float) * input_buffer_size_, 16))),
161 #if defined(WEBRTC_CPU_DETECTION) 163 #if defined(WEBRTC_CPU_DETECTION)
162 convolve_proc_(NULL), 164 convolve_proc_(NULL),
163 #endif 165 #endif
164 r1_(input_buffer_.get()), 166 r1_(input_buffer_.get()),
165 r2_(input_buffer_.get() + kKernelSize / 2) { 167 r2_(input_buffer_.get() + kKernelSize / 2) {
166 #if defined(WEBRTC_CPU_DETECTION) 168 #if defined(WEBRTC_CPU_DETECTION)
167 InitializeCPUSpecificFeatures(); 169 InitializeCPUSpecificFeatures();
168 assert(convolve_proc_); 170 RTC_DCHECK(convolve_proc_);
169 #endif 171 #endif
170 assert(request_frames_ > 0); 172 RTC_DCHECK_GT(request_frames_, 0);
171 Flush(); 173 Flush();
172 assert(block_size_ > kKernelSize); 174 RTC_DCHECK_GT(block_size_, kKernelSize);
173 175
174 memset(kernel_storage_.get(), 0, 176 memset(kernel_storage_.get(), 0,
175 sizeof(*kernel_storage_.get()) * kKernelStorageSize); 177 sizeof(*kernel_storage_.get()) * kKernelStorageSize);
176 memset(kernel_pre_sinc_storage_.get(), 0, 178 memset(kernel_pre_sinc_storage_.get(), 0,
177 sizeof(*kernel_pre_sinc_storage_.get()) * kKernelStorageSize); 179 sizeof(*kernel_pre_sinc_storage_.get()) * kKernelStorageSize);
178 memset(kernel_window_storage_.get(), 0, 180 memset(kernel_window_storage_.get(), 0,
179 sizeof(*kernel_window_storage_.get()) * kKernelStorageSize); 181 sizeof(*kernel_window_storage_.get()) * kKernelStorageSize);
180 182
181 InitializeKernel(); 183 InitializeKernel();
182 } 184 }
183 185
184 SincResampler::~SincResampler() {} 186 SincResampler::~SincResampler() {}
185 187
186 void SincResampler::UpdateRegions(bool second_load) { 188 void SincResampler::UpdateRegions(bool second_load) {
187 // Setup various region pointers in the buffer (see diagram above). If we're 189 // Setup various region pointers in the buffer (see diagram above). If we're
188 // on the second load we need to slide r0_ to the right by kKernelSize / 2. 190 // on the second load we need to slide r0_ to the right by kKernelSize / 2.
189 r0_ = input_buffer_.get() + (second_load ? kKernelSize : kKernelSize / 2); 191 r0_ = input_buffer_.get() + (second_load ? kKernelSize : kKernelSize / 2);
190 r3_ = r0_ + request_frames_ - kKernelSize; 192 r3_ = r0_ + request_frames_ - kKernelSize;
191 r4_ = r0_ + request_frames_ - kKernelSize / 2; 193 r4_ = r0_ + request_frames_ - kKernelSize / 2;
192 block_size_ = r4_ - r2_; 194 block_size_ = r4_ - r2_;
193 195
194 // r1_ at the beginning of the buffer. 196 // r1_ at the beginning of the buffer.
195 assert(r1_ == input_buffer_.get()); 197 RTC_DCHECK_EQ(r1_, input_buffer_.get());
196 // r1_ left of r2_, r4_ left of r3_ and size correct. 198 // r1_ left of r2_, r4_ left of r3_ and size correct.
197 assert(r2_ - r1_ == r4_ - r3_); 199 RTC_DCHECK_EQ(r2_ - r1_, r4_ - r3_);
198 // r2_ left of r3. 200 // r2_ left of r3.
199 assert(r2_ < r3_); 201 RTC_DCHECK_LT(r2_, r3_);
200 } 202 }
201 203
202 void SincResampler::InitializeKernel() { 204 void SincResampler::InitializeKernel() {
203 // Blackman window parameters. 205 // Blackman window parameters.
204 static const double kAlpha = 0.16; 206 static const double kAlpha = 0.16;
205 static const double kA0 = 0.5 * (1.0 - kAlpha); 207 static const double kA0 = 0.5 * (1.0 - kAlpha);
206 static const double kA1 = 0.5; 208 static const double kA1 = 0.5;
207 static const double kA2 = 0.5 * kAlpha; 209 static const double kA2 = 0.5 * kAlpha;
208 210
209 // Generates a set of windowed sinc() kernels. 211 // Generates a set of windowed sinc() kernels.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 const float* const kernel_ptr = kernel_storage_.get(); 278 const float* const kernel_ptr = kernel_storage_.get();
277 while (remaining_frames) { 279 while (remaining_frames) {
278 // |i| may be negative if the last Resample() call ended on an iteration 280 // |i| may be negative if the last Resample() call ended on an iteration
279 // that put |virtual_source_idx_| over the limit. 281 // that put |virtual_source_idx_| over the limit.
280 // 282 //
281 // Note: The loop construct here can severely impact performance on ARM 283 // Note: The loop construct here can severely impact performance on ARM
282 // or when built with clang. See https://codereview.chromium.org/18566009/ 284 // or when built with clang. See https://codereview.chromium.org/18566009/
283 for (int i = static_cast<int>( 285 for (int i = static_cast<int>(
284 ceil((block_size_ - virtual_source_idx_) / current_io_ratio)); 286 ceil((block_size_ - virtual_source_idx_) / current_io_ratio));
285 i > 0; --i) { 287 i > 0; --i) {
286 assert(virtual_source_idx_ < block_size_); 288 RTC_DCHECK_LT(virtual_source_idx_, block_size_);
287 289
288 // |virtual_source_idx_| lies in between two kernel offsets so figure out 290 // |virtual_source_idx_| lies in between two kernel offsets so figure out
289 // what they are. 291 // what they are.
290 const int source_idx = static_cast<int>(virtual_source_idx_); 292 const int source_idx = static_cast<int>(virtual_source_idx_);
291 const double subsample_remainder = virtual_source_idx_ - source_idx; 293 const double subsample_remainder = virtual_source_idx_ - source_idx;
292 294
293 const double virtual_offset_idx = 295 const double virtual_offset_idx =
294 subsample_remainder * kKernelOffsetCount; 296 subsample_remainder * kKernelOffsetCount;
295 const int offset_idx = static_cast<int>(virtual_offset_idx); 297 const int offset_idx = static_cast<int>(virtual_offset_idx);
296 298
297 // We'll compute "convolutions" for the two kernels which straddle 299 // We'll compute "convolutions" for the two kernels which straddle
298 // |virtual_source_idx_|. 300 // |virtual_source_idx_|.
299 const float* const k1 = kernel_ptr + offset_idx * kKernelSize; 301 const float* const k1 = kernel_ptr + offset_idx * kKernelSize;
300 const float* const k2 = k1 + kKernelSize; 302 const float* const k2 = k1 + kKernelSize;
301 303
302 // Ensure |k1|, |k2| are 16-byte aligned for SIMD usage. Should always be 304 // Ensure |k1|, |k2| are 16-byte aligned for SIMD usage. Should always be
303 // true so long as kKernelSize is a multiple of 16. 305 // true so long as kKernelSize is a multiple of 16.
304 assert(0u == (reinterpret_cast<uintptr_t>(k1) & 0x0F)); 306 RTC_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(k1) % 16);
305 assert(0u == (reinterpret_cast<uintptr_t>(k2) & 0x0F)); 307 RTC_DCHECK_EQ(0, reinterpret_cast<uintptr_t>(k2) % 16);
306 308
307 // Initialize input pointer based on quantized |virtual_source_idx_|. 309 // Initialize input pointer based on quantized |virtual_source_idx_|.
308 const float* const input_ptr = r1_ + source_idx; 310 const float* const input_ptr = r1_ + source_idx;
309 311
310 // Figure out how much to weight each kernel's "convolution". 312 // Figure out how much to weight each kernel's "convolution".
311 const double kernel_interpolation_factor = 313 const double kernel_interpolation_factor =
312 virtual_offset_idx - offset_idx; 314 virtual_offset_idx - offset_idx;
313 *destination++ = CONVOLVE_FUNC( 315 *destination++ = CONVOLVE_FUNC(
314 input_ptr, k1, k2, kernel_interpolation_factor); 316 input_ptr, k1, k2, kernel_interpolation_factor);
315 317
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 sum1 += *input_ptr * *k1++; 365 sum1 += *input_ptr * *k1++;
364 sum2 += *input_ptr++ * *k2++; 366 sum2 += *input_ptr++ * *k2++;
365 } 367 }
366 368
367 // Linearly interpolate the two "convolutions". 369 // Linearly interpolate the two "convolutions".
368 return static_cast<float>((1.0 - kernel_interpolation_factor) * sum1 + 370 return static_cast<float>((1.0 - kernel_interpolation_factor) * sum1 +
369 kernel_interpolation_factor * sum2); 371 kernel_interpolation_factor * sum2);
370 } 372 }
371 373
372 } // namespace webrtc 374 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/common_audio/fir_filter_sse.cc ('k') | webrtc/common_types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698