Bug 1265403 - Support chaining AudioParam automation methods. r?smaug
MozReview-Commit-ID: 7Jh5eWtfU4t
--- a/dom/media/webaudio/AudioParam.h
+++ b/dom/media/webaudio/AudioParam.h
@@ -39,27 +39,31 @@ public:
{
return mNode->Context();
}
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
// We override SetValueCurveAtTime to convert the Float32Array to the wrapper
// object.
- void SetValueCurveAtTime(const Float32Array& aValues, double aStartTime, double aDuration, ErrorResult& aRv)
+ AudioParam* SetValueCurveAtTime(const Float32Array& aValues,
+ double aStartTime,
+ double aDuration,
+ ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return;
+ return this;
}
aValues.ComputeLengthAndData();
EventInsertionHelper(aRv, AudioTimelineEvent::SetValueCurve,
aStartTime, 0.0f, 0.0f, aDuration, aValues.Data(),
aValues.Length());
+ return this;
}
void SetValue(float aValue)
{
AudioTimelineEvent event(AudioTimelineEvent::SetValue, 0.0f, aValue);
ErrorResult rv;
if (!ValidateEvent(event, rv)) {
@@ -68,71 +72,81 @@ public:
return;
}
AudioParamTimeline::SetValue(aValue);
SendEventToEngine(event);
}
- void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
+ AudioParam* SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return;
+ return this;
}
EventInsertionHelper(aRv, AudioTimelineEvent::SetValueAtTime,
aStartTime, aValue);
+
+ return this;
}
- void LinearRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
+ AudioParam* LinearRampToValueAtTime(float aValue, double aEndTime,
+ ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aEndTime)) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return;
+ return this;
}
EventInsertionHelper(aRv, AudioTimelineEvent::LinearRamp, aEndTime, aValue);
+ return this;
}
- void ExponentialRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
+ AudioParam* ExponentialRampToValueAtTime(float aValue, double aEndTime,
+ ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aEndTime)) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return;
+ return this;
}
EventInsertionHelper(aRv, AudioTimelineEvent::ExponentialRamp,
aEndTime, aValue);
+ return this;
}
- void SetTargetAtTime(float aTarget, double aStartTime,
- double aTimeConstant, ErrorResult& aRv)
+ AudioParam* SetTargetAtTime(float aTarget, double aStartTime,
+ double aTimeConstant, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aStartTime) ||
!WebAudioUtils::IsTimeValid(aTimeConstant)) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return;
+ return this;
}
EventInsertionHelper(aRv, AudioTimelineEvent::SetTarget,
aStartTime, aTarget,
aTimeConstant);
+
+ return this;
}
- void CancelScheduledValues(double aStartTime, ErrorResult& aRv)
+ AudioParam* CancelScheduledValues(double aStartTime, ErrorResult& aRv)
{
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
- return;
+ return this;
}
// Remove some events on the main thread copy.
AudioEventTimeline::CancelScheduledValues(aStartTime);
AudioTimelineEvent event(AudioTimelineEvent::Cancel, aStartTime, 0.0f);
SendEventToEngine(event);
+
+ return this;
}
uint32_t ParentNodeId()
{
return mNode->Id();
}
void GetName(nsAString& aName)
--- a/dom/media/webaudio/test/mochitest.ini
+++ b/dom/media/webaudio/test/mochitest.ini
@@ -50,16 +50,17 @@ skip-if = (toolkit == 'gonk') || (toolki
[test_audioBufferSourceNodeRate.html]
[test_AudioContext.html]
[test_audioContextSuspendResumeClose.html]
skip-if = buildapp == 'mulet'
tags=capturestream
[test_audioDestinationNode.html]
[test_AudioListener.html]
[test_AudioNodeDevtoolsAPI.html]
+[test_audioParamChaining.html]
[test_AudioParamDevtoolsAPI.html]
[test_audioParamExponentialRamp.html]
[test_audioParamGain.html]
[test_audioParamLinearRamp.html]
[test_audioParamSetCurveAtTime.html]
[test_audioParamSetCurveAtTimeTwice.html]
[test_audioParamSetCurveAtTimeZeroDuration.html]
[test_audioParamSetTargetAtTime.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/webaudio/test/test_audioParamChaining.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test whether we can create an AudioContext interface</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish()
+
+function frameToTime(frame, rate)
+{
+ return frame / rate;
+}
+
+const RATE = 44100;
+
+var oc = new OfflineAudioContext(1, 44100, RATE);
+// This allows us to have a source that is simply a DC offset.
+var source = oc.createBufferSource();
+var buf = oc.createBuffer(1, 1, RATE);
+buf.getChannelData(0)[0] = 1;
+source.loop = true;
+source.buffer = buf;
+
+source.start(0);
+
+var gain = oc.createGain();
+
+source.connect(gain).connect(oc.destination);
+
+// We chain three uutomation methods, making a gain step.
+var rv = gain.gain.setValueAtTime(0, frameToTime(0, RATE))
+ .setValueAtTime(0.5, frameToTime(22000, RATE))
+ .setValueAtTime(1, frameToTime(44000, RATE));
+
+ok(rv instanceof AudioParam);
+ok(rv == gain.gain);
+
+oc.startRendering().then(function(rendered) {
+ console.log(rendered.getChannelData(0));
+ ok(rendered.getChannelData(0)[0] == 0);
+ ok(rendered.getChannelData(0)[22050] == 0.5);
+ ok(rendered.getChannelData(0)[44099] == 1);
+ SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/webidl/AudioParam.webidl
+++ b/dom/webidl/AudioParam.webidl
@@ -12,34 +12,34 @@
interface AudioParam {
attribute float value;
readonly attribute float defaultValue;
// Parameter automation.
[Throws]
- void setValueAtTime(float value, double startTime);
+ AudioParam setValueAtTime(float value, double startTime);
[Throws]
- void linearRampToValueAtTime(float value, double endTime);
+ AudioParam linearRampToValueAtTime(float value, double endTime);
[Throws]
- void exponentialRampToValueAtTime(float value, double endTime);
+ AudioParam exponentialRampToValueAtTime(float value, double endTime);
// Exponentially approach the target value with a rate having the given time constant.
[Throws]
- void setTargetAtTime(float target, double startTime, double timeConstant);
+ AudioParam setTargetAtTime(float target, double startTime, double timeConstant);
// Sets an array of arbitrary parameter values starting at time for the given duration.
// The number of values will be scaled to fit into the desired duration.
[Throws]
- void setValueCurveAtTime(Float32Array values, double startTime, double duration);
+ AudioParam setValueCurveAtTime(Float32Array values, double startTime, double duration);
// Cancels all scheduled parameter changes with times greater than or equal to startTime.
[Throws]
- void cancelScheduledValues(double startTime);
+ AudioParam cancelScheduledValues(double startTime);
};
// Mozilla extension
partial interface AudioParam {
// The ID of the AudioNode this AudioParam belongs to.
[ChromeOnly]
readonly attribute unsigned long parentNodeId;