зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1313058 - Fix SetValueCurveAtTime interpolation; r=padenot
This interpolates over aCurveLength - 1 steps rather than over aCurveLength steps as was done before. Previously we would reach the final value on the curve before the end of the specified duration. For example, on the curve [1.0, 0.0] with duration 1000, we would interpolate from 1.0 to 0.0 by time 500 rather than time 1000. With these changes, we don't reach 0.0 until time 1000, as expected. This also updates TestSpecExample in TestAudioEventTimeline.cpp to match the curve in the latest spec. MozReview-Commit-ID: Cgs8csbRUMh --HG-- extra : rebase_source : 1960128558ae9174933cd5be3c1fbfcb79f5ba1d
This commit is contained in:
Родитель
9c3d575a0f
Коммит
98715f6438
|
@ -37,11 +37,12 @@ static float ExtractValueFromCurve(double startTime, float* aCurve, uint32_t aCu
|
|||
if (ratio >= 1.0) {
|
||||
return aCurve[aCurveLength - 1];
|
||||
}
|
||||
uint32_t current = uint32_t(aCurveLength * ratio);
|
||||
uint32_t current = uint32_t(floor((aCurveLength - 1) * ratio));
|
||||
uint32_t next = current + 1;
|
||||
double step = duration / double(aCurveLength - 1);
|
||||
if (next < aCurveLength) {
|
||||
double t0 = double(current) / double(aCurveLength) * duration ;
|
||||
double t1 = double(next) / double(aCurveLength) * duration ;
|
||||
double t0 = current * step;
|
||||
double t1 = next * step;
|
||||
return LinearInterpolate(t0, aCurve[current], t1, aCurve[next], t - startTime);
|
||||
} else {
|
||||
return aCurve[current];
|
||||
|
|
|
@ -102,7 +102,11 @@ void TestSpecExample()
|
|||
|
||||
ErrorResultMock rv;
|
||||
|
||||
float curve[] = { -1.0f, 0.0f, 1.0f };
|
||||
uint32_t curveLength = 44100;
|
||||
float* curve = new float[curveLength];
|
||||
for (uint32_t i = 0; i < curveLength; ++i) {
|
||||
curve[i] = sin(M_PI * i / float(curveLength));
|
||||
}
|
||||
|
||||
// This test is copied from the example in the Web Audio spec
|
||||
const double t0 = 0.0,
|
||||
|
@ -127,7 +131,7 @@ void TestSpecExample()
|
|||
is(rv, NS_OK, "ExponentialRampToValueAtTime succeeded");
|
||||
timeline.ExponentialRampToValueAtTime(0.05f, t6, rv);
|
||||
is(rv, NS_OK, "ExponentialRampToValueAtTime succeeded");
|
||||
timeline.SetValueCurveAtTime(curve, ArrayLength(curve), t6, t7 - t6, rv);
|
||||
timeline.SetValueCurveAtTime(curve, curveLength, t6, t7 - t6, rv);
|
||||
is(rv, NS_OK, "SetValueCurveAtTime succeeded");
|
||||
|
||||
is(timeline.GetValueAtTime(0.0), 0.2f, "Correct value");
|
||||
|
@ -144,10 +148,11 @@ void TestSpecExample()
|
|||
is(timeline.GetValueAtTime(0.55), (0.15f * powf(0.75f / 0.15f, 0.15f / 0.2f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.6), 0.75f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.65), (0.75f * powf(0.05f / 0.75f, 0.5f)), "Correct value");
|
||||
is(timeline.GetValueAtTime(0.7), -1.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.8), 0.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.9), 1.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(1.0), 1.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.7), 0.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(0.85), 1.0f, "Correct value");
|
||||
is(timeline.GetValueAtTime(1.0), curve[curveLength - 1], "Correct value");
|
||||
|
||||
delete[] curve;
|
||||
}
|
||||
|
||||
void TestInvalidEvents()
|
||||
|
|
|
@ -30,13 +30,14 @@ var gTest = {
|
|||
this.curve = new Float32Array([1.0, 0.5, 0.75, 0.25]);
|
||||
var expectedBuffer = context.createBuffer(1, 2048, context.sampleRate);
|
||||
var data = expectedBuffer.getChannelData(0);
|
||||
var step = 1024 / 3;
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
if (i < 256) {
|
||||
data[i] = 1.0 - 0.5*i/256;
|
||||
} else if (i < 512) {
|
||||
data[i] = 0.5 + 0.25*(i - 256)/256;
|
||||
} else if (i < 768) {
|
||||
data[i] = 0.75 - 0.5*(i - 512)/256;
|
||||
if (i < step) {
|
||||
data[i] = 1.0 - 0.5*i/step;
|
||||
} else if (i < 2*step) {
|
||||
data[i] = 0.5 + 0.25*(i - step)/step;
|
||||
} else if (i < 3*step) {
|
||||
data[i] = 0.75 - 0.5*(i - 2*step)/step;
|
||||
} else {
|
||||
data[i] = 0.25;
|
||||
}
|
||||
|
|
|
@ -47,15 +47,13 @@ var gTest = {
|
|||
}
|
||||
var expectedBuffer = context.createBuffer(1, 2048, context.sampleRate);
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
var t = i / context.sampleRate;
|
||||
var current = Math.min(99, Math.floor(100 * Math.min(1.0, (t - T0) / this.duration)));
|
||||
step = 1024.0/99.0;
|
||||
var current = Math.floor(i / step);
|
||||
var next = current + 1;
|
||||
if (next < this.curve.length) {
|
||||
var t0 = current / this.curve.length * this.duration;
|
||||
var t1 = next / this.curve.length * this.duration;
|
||||
expectedBuffer.getChannelData(0)[i] = linearInterpolate(t0, this.curve[current], t1, this.curve[next], t);
|
||||
expectedBuffer.getChannelData(0)[i] = linearInterpolate(current*step, this.curve[current], next*step, this.curve[next], i);
|
||||
} else {
|
||||
expectedBuffer.getChannelData(0)[i] = this.curve[current];
|
||||
expectedBuffer.getChannelData(0)[i] = this.curve[99];
|
||||
}
|
||||
}
|
||||
return expectedBuffer;
|
||||
|
|
Загрузка…
Ссылка в новой задаче