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

Side by Side Diff: media/filters/wsola_internals.cc

Issue 217553004: Handle near-colinear case in WSOLAS QuadraticInterpolation better. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 months 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // MSVC++ requires this to be set before any other includes to get M_PI. 5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES 6 #define _USE_MATH_DEFINES
7 7
8 #include "media/filters/wsola_internals.h" 8 #include "media/filters/wsola_internals.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 energy[k + n * channels] = energy[k + (n - 1) * channels] - *slide_out * 80 energy[k + n * channels] = energy[k + (n - 1) * channels] - *slide_out *
81 *slide_out + *slide_in * *slide_in; 81 *slide_out + *slide_in * *slide_in;
82 } 82 }
83 } 83 }
84 } 84 }
85 85
86 // Fit the curve f(x) = a * x^2 + b * x + c such that 86 // Fit the curve f(x) = a * x^2 + b * x + c such that
87 // f(-1) = |y[0]| 87 // f(-1) = |y[0]|
88 // f(0) = |y[1]| 88 // f(0) = |y[1]|
89 // f(1) = |y[2]|. 89 // f(1) = |y[2]|.
90 void CubicInterpolation(const float* y_values, 90 void QuadraticInterpolation(const float* y_values,
91 float* extremum, 91 float* extremum,
92 float* extremum_value) { 92 float* extremum_value) {
93 float a = 0.5f * (y_values[2] + y_values[0]) - y_values[1]; 93 float a = 0.5f * (y_values[2] + y_values[0]) - y_values[1];
94 float b = 0.5f * (y_values[2] - y_values[0]); 94 float b = 0.5f * (y_values[2] - y_values[0]);
95 float c = y_values[1]; 95 float c = y_values[1];
96 96
97 DCHECK_NE(a, 0); 97 if (a == 0.f || fabsf(2.f * a) < fabsf(b)) {
turajs1 2014/03/31 23:18:42 abs(2*a) is always larger or equal to abs(b), beca
sandersd (OOO until July 31) 2014/04/01 00:27:49 After some experimentation, I have concluded that
98 *extremum = -b / (2.f * a); 98 // The quadratic's maximum does not exist or is outside -1 <= x <= 1. Since
99 *extremum_value = a * (*extremum) * (*extremum) + b * (*extremum) + c; 99 // having a local maximum is a precondition to calling this method, it means
100 // that floating point error is dominating. Conveniently that also means the
101 // range is small, so any point will be a good approximation.
102 *extremum = 0;
103 *extremum_value = y_values[1];
104 } else {
105 *extremum = -b / (2.f * a);
106 *extremum_value = a * (*extremum) * (*extremum) + b * (*extremum) + c;
107 }
100 } 108 }
101 109
102 int DecimatedSearch(int decimation, 110 int DecimatedSearch(int decimation,
103 Interval exclude_interval, 111 Interval exclude_interval,
104 const AudioBus* target_block, 112 const AudioBus* target_block,
105 const AudioBus* search_segment, 113 const AudioBus* search_segment,
106 const float* energy_target_block, 114 const float* energy_target_block,
107 const float* energy_candidate_blocks) { 115 const float* energy_candidate_blocks) {
108 int channels = search_segment->channels(); 116 int channels = search_segment->channels();
109 int block_size = target_block->frames(); 117 int block_size = target_block->frames();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 similarity[2] = MultiChannelSimilarityMeasure( 155 similarity[2] = MultiChannelSimilarityMeasure(
148 dot_prod.get(), energy_target_block, 156 dot_prod.get(), energy_target_block,
149 &energy_candidate_blocks[n * channels], channels); 157 &energy_candidate_blocks[n * channels], channels);
150 158
151 if ((similarity[1] > similarity[0] && similarity[1] >= similarity[2]) || 159 if ((similarity[1] > similarity[0] && similarity[1] >= similarity[2]) ||
152 (similarity[1] >= similarity[0] && similarity[1] > similarity[2])) { 160 (similarity[1] >= similarity[0] && similarity[1] > similarity[2])) {
153 // A local maximum is found. Do a cubic interpolation for a better 161 // A local maximum is found. Do a cubic interpolation for a better
154 // estimate of candidate maximum. 162 // estimate of candidate maximum.
155 float normalized_candidate_index; 163 float normalized_candidate_index;
156 float candidate_similarity; 164 float candidate_similarity;
157 CubicInterpolation(similarity, &normalized_candidate_index, 165 QuadraticInterpolation(similarity, &normalized_candidate_index,
158 &candidate_similarity); 166 &candidate_similarity);
159 167
160 int candidate_index = n - decimation + static_cast<int>( 168 int candidate_index = n - decimation + static_cast<int>(
161 normalized_candidate_index * decimation + 0.5f); 169 normalized_candidate_index * decimation + 0.5f);
162 if (candidate_similarity > best_similarity && 170 if (candidate_similarity > best_similarity &&
163 !InInterval(candidate_index, exclude_interval)) { 171 !InInterval(candidate_index, exclude_interval)) {
164 optimal_index = candidate_index; 172 optimal_index = candidate_index;
165 best_similarity = candidate_similarity; 173 best_similarity = candidate_similarity;
166 } 174 }
167 } else if (n + decimation >= num_candidate_blocks && 175 } else if (n + decimation >= num_candidate_blocks &&
168 similarity[2] > best_similarity && 176 similarity[2] > best_similarity &&
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 void GetSymmetricHanningWindow(int window_length, float* window) { 263 void GetSymmetricHanningWindow(int window_length, float* window) {
256 const float scale = 2.0f * M_PI / window_length; 264 const float scale = 2.0f * M_PI / window_length;
257 for (int n = 0; n < window_length; ++n) 265 for (int n = 0; n < window_length; ++n)
258 window[n] = 0.5f * (1.0f - cosf(n * scale)); 266 window[n] = 0.5f * (1.0f - cosf(n * scale));
259 } 267 }
260 268
261 } // namespace internal 269 } // namespace internal
262 270
263 } // namespace media 271 } // namespace media
264 272
OLDNEW
« media/filters/audio_renderer_algorithm_unittest.cc ('K') | « media/filters/wsola_internals.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698