Index: media/filters/wsola_internals.cc |
diff --git a/media/filters/wsola_internals.cc b/media/filters/wsola_internals.cc |
index 45cdd8ffad5de606c74a9165eb2dfd0d720b8816..208f8ead40ace6d2e784263a3ffc8eb75f116e4c 100644 |
--- a/media/filters/wsola_internals.cc |
+++ b/media/filters/wsola_internals.cc |
@@ -87,16 +87,24 @@ void MultiChannelMovingBlockEnergies(const AudioBus* input, |
// f(-1) = |y[0]| |
// f(0) = |y[1]| |
// f(1) = |y[2]|. |
-void CubicInterpolation(const float* y_values, |
- float* extremum, |
- float* extremum_value) { |
+void QuadraticInterpolation(const float* y_values, |
+ float* extremum, |
+ float* extremum_value) { |
float a = 0.5f * (y_values[2] + y_values[0]) - y_values[1]; |
float b = 0.5f * (y_values[2] - y_values[0]); |
float c = y_values[1]; |
- DCHECK_NE(a, 0); |
- *extremum = -b / (2.f * a); |
- *extremum_value = a * (*extremum) * (*extremum) + b * (*extremum) + c; |
+ 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
|
+ // The quadratic's maximum does not exist or is outside -1 <= x <= 1. Since |
+ // having a local maximum is a precondition to calling this method, it means |
+ // that floating point error is dominating. Conveniently that also means the |
+ // range is small, so any point will be a good approximation. |
+ *extremum = 0; |
+ *extremum_value = y_values[1]; |
+ } else { |
+ *extremum = -b / (2.f * a); |
+ *extremum_value = a * (*extremum) * (*extremum) + b * (*extremum) + c; |
+ } |
} |
int DecimatedSearch(int decimation, |
@@ -154,8 +162,8 @@ int DecimatedSearch(int decimation, |
// estimate of candidate maximum. |
float normalized_candidate_index; |
float candidate_similarity; |
- CubicInterpolation(similarity, &normalized_candidate_index, |
- &candidate_similarity); |
+ QuadraticInterpolation(similarity, &normalized_candidate_index, |
+ &candidate_similarity); |
int candidate_index = n - decimation + static_cast<int>( |
normalized_candidate_index * decimation + 0.5f); |