Bug 1265401 - Perform linear interpolation when computing the SetValueCurveAtTime events; r=padenot

MozReview-Commit-ID: IOiyq5a4P2A

--HG--
extra : rebase_source : b3d225348d6b8c9dd8b4b20eb11e8ec65413a52e
This commit is contained in:
Dan Minor 2016-10-24 13:07:32 -04:00
parent 947371cedb
commit 50b4412911
3 changed files with 39 additions and 25 deletions

View File

@ -37,7 +37,15 @@ static float ExtractValueFromCurve(double startTime, float* aCurve, uint32_t aCu
if (ratio >= 1.0) {
return aCurve[aCurveLength - 1];
}
return aCurve[uint32_t(aCurveLength * ratio)];
uint32_t current = uint32_t(aCurveLength * ratio);
uint32_t next = current + 1;
if (next < aCurveLength) {
double t0 = double(current) / double(aCurveLength) * duration ;
double t1 = double(next) / double(aCurveLength) * duration ;
return LinearInterpolate(t0, aCurve[current], t1, aCurve[next], t - startTime);
} else {
return aCurve[current];
}
}
namespace mozilla {

View File

@ -16,17 +16,10 @@ var gTest = {
length: 2048,
numberOfChannels: 1,
createGraph: function(context) {
var sourceBuffer = context.createBuffer(1, 2048, context.sampleRate);
for (var i = 0; i < 2048; ++i) {
sourceBuffer.getChannelData(0)[i] = 1;
}
var source = context.createBufferSource();
source.buffer = sourceBuffer;
var source = context.createConstantSource();
var gain = context.createGain();
gain.gain.setValueCurveAtTime(this.curve, T0, this.duration);
source.connect(gain);
source.start(0);
@ -34,14 +27,19 @@ var gTest = {
},
createExpectedBuffers: function(context) {
this.duration = 1024 / context.sampleRate;
this.curve = new Float32Array(100);
for (var i = 0; i < 100; ++i) {
this.curve[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
}
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);
for (var i = 0; i < 2048; ++i) {
var t = i / context.sampleRate;
expectedBuffer.getChannelData(0)[i] = this.curve[Math.min(99, Math.floor(100 * Math.min(1.0, (t - T0) / this.duration)))];
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;
} else {
data[i] = 0.25;
}
}
return expectedBuffer;
},

View File

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test AudioParam.linearRampToValue</title>
<title>Test AudioParam.setValueCurveAtTime twice</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="webaudio.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
@ -10,28 +10,28 @@
<pre id="test">
<script class="testbody" type="text/javascript">
function linearInterpolate(t0, v0, t1, v1, t)
{
return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
}
var T0 = 0;
var gTest = {
length: 2048,
numberOfChannels: 1,
createGraph: function(context) {
var sourceBuffer = context.createBuffer(1, 2048, context.sampleRate);
for (var i = 0; i < 2048; ++i) {
sourceBuffer.getChannelData(0)[i] = 1;
}
var curve2 = new Float32Array(100);
for (var i = 0; i < 100; ++i) {
curve2[i] = Math.sin(220 * 6 * Math.PI * i / context.sampleRate);
}
var source = context.createBufferSource();
source.buffer = sourceBuffer;
var source = context.createConstantSource();
var gain = context.createGain();
gain.gain.setValueCurveAtTime(curve2, T0, this.duration/2);
//Set a diffrent curve from the first one
//Set a different curve from the first one
gain.gain.setValueCurveAtTime(this.curve, T0, this.duration);
source.connect(gain);
@ -48,7 +48,15 @@ var gTest = {
var expectedBuffer = context.createBuffer(1, 2048, context.sampleRate);
for (var i = 0; i < 2048; ++i) {
var t = i / context.sampleRate;
expectedBuffer.getChannelData(0)[i] = this.curve[Math.min(99, Math.floor(100 * Math.min(1.0, (t - T0) / this.duration)))];
var current = Math.min(99, Math.floor(100 * Math.min(1.0, (t - T0) / this.duration)));
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);
} else {
expectedBuffer.getChannelData(0)[i] = this.curve[current];
}
}
return expectedBuffer;
},