Bug 813269 - Use double to represent time in Web Audio; r=bzbarsky

This commit is contained in:
Ehsan Akhgari 2012-11-19 15:52:29 -05:00
parent 8980d5151e
commit 50dab9a21f
12 changed files with 80 additions and 80 deletions

View File

@ -59,9 +59,9 @@ public:
return mLength;
}
float Duration() const
double Duration() const
{
return mLength / mSampleRate;
return mLength / static_cast<double> (mSampleRate);
}
uint32_t NumberOfChannels() const

View File

@ -104,9 +104,9 @@ AudioContext::CreateGain()
}
already_AddRefed<DelayNode>
AudioContext::CreateDelay(float aMaxDelayTime, ErrorResult& aRv)
AudioContext::CreateDelay(double aMaxDelayTime, ErrorResult& aRv)
{
if (aMaxDelayTime > 0.f && aMaxDelayTime < 3.f) {
if (aMaxDelayTime > 0. && aMaxDelayTime < 3.) {
nsRefPtr<DelayNode> delayNode = new DelayNode(this, aMaxDelayTime);
return delayNode.forget();
}

View File

@ -73,7 +73,7 @@ public:
CreateGain();
already_AddRefed<DelayNode>
CreateDelay(float aMaxDelayTime, ErrorResult& aRv);
CreateDelay(double aMaxDelayTime, ErrorResult& aRv);
already_AddRefed<PannerNode>
CreatePanner();

View File

@ -41,11 +41,11 @@ private:
SetValueCurve
};
Event(Type aType, float aTime, float aValue, float aTimeConstant = 0.0,
Event(Type aType, double aTime, float aValue, double aTimeConstant = 0.0,
float aDuration = 0.0, FloatArrayWrapper aCurve = FloatArrayWrapper())
: mType(aType)
, mTime(aTime)
, mValue(aValue)
, mTime(aTime)
, mTimeConstant(aTimeConstant)
, mDuration(aDuration)
{
@ -63,10 +63,10 @@ private:
}
Type mType;
float mTime;
float mValue;
float mTimeConstant;
float mDuration;
double mTime;
double mTimeConstant;
double mDuration;
FloatArrayWrapper mCurve;
private:
@ -125,33 +125,33 @@ public:
return mDefaultValue;
}
void SetValueAtTime(float aValue, float aStartTime, ErrorResult& aRv)
void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
{
InsertEvent(Event(Event::SetValue, aStartTime, aValue), aRv);
}
void LinearRampToValueAtTime(float aValue, float aEndTime, ErrorResult& aRv)
void LinearRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
{
InsertEvent(Event(Event::LinearRamp, aEndTime, aValue), aRv);
}
void ExponentialRampToValueAtTime(float aValue, float aEndTime, ErrorResult& aRv)
void ExponentialRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
{
InsertEvent(Event(Event::ExponentialRamp, aEndTime, aValue), aRv);
}
void SetTargetAtTime(float aTarget, float aStartTime, float aTimeConstant, ErrorResult& aRv)
void SetTargetAtTime(float aTarget, double aStartTime, double aTimeConstant, ErrorResult& aRv)
{
InsertEvent(Event(Event::SetTarget, aStartTime, aTarget, aTimeConstant), aRv);
}
void SetValueCurveAtTime(const FloatArrayWrapper& aValues, float aStartTime, float aDuration, ErrorResult& aRv)
void SetValueCurveAtTime(const FloatArrayWrapper& aValues, double aStartTime, double aDuration, ErrorResult& aRv)
{
// TODO: implement
// InsertEvent(Event(Event::SetValueCurve, aStartTime, 0.0f, 0.0f, aDuration, aValues), aRv);
}
void CancelScheduledValues(float aStartTime)
void CancelScheduledValues(double aStartTime)
{
for (unsigned i = 0; i < mEvents.Length(); ++i) {
if (mEvents[i].mTime >= aStartTime) {
@ -169,7 +169,7 @@ public:
}
// This method computes the AudioParam value at a given time based on the event timeline
float GetValueAtTime(float aTime) const
float GetValueAtTime(double aTime) const
{
const Event* previous = nullptr;
const Event* next = nullptr;
@ -222,10 +222,10 @@ public:
return mValue;
case Event::LinearRamp:
// Use t=0 as T0 and v=defaultValue as V0
return LinearInterpolate(0.0f, mValue, next->mTime, next->mValue, aTime);
return LinearInterpolate(0.0, mValue, next->mTime, next->mValue, aTime);
case Event::ExponentialRamp:
// Use t=0 as T0 and v=defaultValue as V0
return ExponentialInterpolate(0.0f, mValue, next->mTime, next->mValue, aTime);
return ExponentialInterpolate(0.0, mValue, next->mTime, next->mValue, aTime);
case Event::SetValueCurve:
// TODO: implement
return 0.0f;
@ -296,17 +296,17 @@ public:
return mEvents.Length();
}
static float LinearInterpolate(float t0, float v0, float t1, float v1, float t)
static float LinearInterpolate(double t0, float v0, double t1, float v1, double t)
{
return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
}
static float ExponentialInterpolate(float t0, float v0, float t1, float v1, float t)
static float ExponentialInterpolate(double t0, float v0, double t1, float v1, double t)
{
return v0 * powf(v1 / v0, (t - t0) / (t1 - t0));
}
static float ExponentialApproach(float t0, float v0, float v1, float timeConstant, float t)
static float ExponentialApproach(double t0, double v0, float v1, double timeConstant, double t)
{
return v1 + (v0 - v1) * expf(-(t - t0) / timeConstant);
}

View File

@ -44,7 +44,7 @@ AudioParam::~AudioParam()
JSObject*
AudioParam::WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap)
bool* aTriedToWrap)
{
return AudioParamBinding::Wrap(aCx, aScope, this, aTriedToWrap);
}

View File

@ -102,7 +102,7 @@ public:
// We override SetValueCurveAtTime to convert the Float32Array to the wrapper
// object.
void SetValueCurveAtTime(JSContext* cx, const Float32Array& aValues, float aStartTime, float aDuration, ErrorResult& aRv)
void SetValueCurveAtTime(JSContext* cx, const Float32Array& aValues, double aStartTime, double aDuration, ErrorResult& aRv)
{
AudioParamTimeline::SetValueCurveAtTime(detail::FloatArrayWrapper(aValues),
aStartTime, aDuration, aRv);

View File

@ -24,7 +24,7 @@ NS_INTERFACE_MAP_END_INHERITING(AudioNode)
NS_IMPL_ADDREF_INHERITED(DelayNode, AudioNode)
NS_IMPL_RELEASE_INHERITED(DelayNode, AudioNode)
DelayNode::DelayNode(AudioContext* aContext, float aMaxDelay)
DelayNode::DelayNode(AudioContext* aContext, double aMaxDelay)
: AudioNode(aContext)
, mDelay(new AudioParam(aContext, 0.0f, 0.0f, aMaxDelay))
{

View File

@ -18,7 +18,7 @@ class AudioContext;
class DelayNode : public AudioNode
{
public:
DelayNode(AudioContext* aContext, float aMaxDelay);
DelayNode(AudioContext* aContext, double aMaxDelay);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DelayNode, AudioNode)

View File

@ -105,14 +105,14 @@ void TestSpecExample()
ErrorResultMock rv;
// This test is copied from the example in the Web Audio spec
const float t0 = 0.0f,
t1 = 0.1f,
t2 = 0.2f,
t3 = 0.3f,
t4 = 0.4f,
t5 = 0.6f,
t6 = 0.7f/*,
t7 = 1.0f*/;
const float t0 = 0.0,
t1 = 0.1,
t2 = 0.2,
t3 = 0.3,
t4 = 0.4,
t5 = 0.6,
t6 = 0.7/*,
t7 = 1.0*/;
timeline.SetValueAtTime(0.2f, t0, rv);
is(rv, NS_OK, "SetValueAtTime succeeded");
timeline.SetValueAtTime(0.3f, t1, rv);
@ -156,35 +156,35 @@ void TestInvalidEvents()
ErrorResultMock rv;
timeline.SetValueAtTime(NaN, 0.1f, rv);
timeline.SetValueAtTime(NaN, 0.1, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetValueAtTime(Infinity, 0.1f, rv);
timeline.SetValueAtTime(Infinity, 0.1, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetValueAtTime(-Infinity, 0.1f, rv);
timeline.SetValueAtTime(-Infinity, 0.1, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.LinearRampToValueAtTime(NaN, 0.2f, rv);
timeline.LinearRampToValueAtTime(NaN, 0.2, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.LinearRampToValueAtTime(Infinity, 0.2f, rv);
timeline.LinearRampToValueAtTime(Infinity, 0.2, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.LinearRampToValueAtTime(-Infinity, 0.2f, rv);
timeline.LinearRampToValueAtTime(-Infinity, 0.2, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.ExponentialRampToValueAtTime(NaN, 0.3f, rv);
timeline.ExponentialRampToValueAtTime(NaN, 0.3, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.ExponentialRampToValueAtTime(Infinity, 0.3f, rv);
timeline.ExponentialRampToValueAtTime(Infinity, 0.3, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.ExponentialRampToValueAtTime(-Infinity, 0.4f, rv);
timeline.ExponentialRampToValueAtTime(-Infinity, 0.4, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetTargetAtTime(NaN, 0.4f, 1.0f, rv);
timeline.SetTargetAtTime(NaN, 0.4, 1.0, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetTargetAtTime(Infinity, 0.4f, 1.0f, rv);
timeline.SetTargetAtTime(Infinity, 0.4, 1.0, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetTargetAtTime(-Infinity, 0.4f, 1.0f, rv);
timeline.SetTargetAtTime(-Infinity, 0.4, 1.0, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetTargetAtTime(0.4f, NaN, 1.0f, rv);
timeline.SetTargetAtTime(0.4f, NaN, 1.0, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetTargetAtTime(0.4f, Infinity, 1.0f, rv);
timeline.SetTargetAtTime(0.4f, Infinity, 1.0, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
timeline.SetTargetAtTime(0.4f, -Infinity, 1.0f, rv);
timeline.SetTargetAtTime(0.4f, -Infinity, 1.0, rv);
is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
// TODO: Test SetValueCurveAtTime
}
@ -196,13 +196,13 @@ void TestEventReplacement()
ErrorResultMock rv;
is(timeline.GetEventCount(), 0, "No events yet");
timeline.SetValueAtTime(10.0f, 0.1f, rv);
timeline.SetValueAtTime(10.0f, 0.1, rv);
is(timeline.GetEventCount(), 1, "One event scheduled now");
timeline.SetValueAtTime(20.0f, 0.1f, rv);
timeline.SetValueAtTime(20.0f, 0.1, rv);
is(rv, NS_OK, "Event scheduling should be successful");
is(timeline.GetEventCount(), 1, "Event should be replaced");
is(timeline.GetValueAtTime(0.1f), 20.0f, "The first event should be overwritten");
timeline.LinearRampToValueAtTime(30.0f, 0.1f, rv);
timeline.LinearRampToValueAtTime(30.0f, 0.1, rv);
is(rv, NS_OK, "Event scheduling should be successful");
is(timeline.GetEventCount(), 2, "Different event type should be appended");
is(timeline.GetValueAtTime(0.1f), 30.0f, "The first event should be overwritten");
@ -214,16 +214,16 @@ void TestEventRemoval()
ErrorResultMock rv;
timeline.SetValueAtTime(10.0f, 0.1f, rv);
timeline.SetValueAtTime(15.0f, 0.15f, rv);
timeline.SetValueAtTime(20.0f, 0.2f, rv);
timeline.LinearRampToValueAtTime(30.0f, 0.3f, rv);
timeline.SetValueAtTime(10.0f, 0.1, rv);
timeline.SetValueAtTime(15.0f, 0.15, rv);
timeline.SetValueAtTime(20.0f, 0.2, rv);
timeline.LinearRampToValueAtTime(30.0f, 0.3, rv);
is(timeline.GetEventCount(), 4, "Should have three events initially");
timeline.CancelScheduledValues(0.4f);
timeline.CancelScheduledValues(0.4);
is(timeline.GetEventCount(), 4, "Trying to delete past the end of the array should have no effect");
timeline.CancelScheduledValues(0.3f);
timeline.CancelScheduledValues(0.3);
is(timeline.GetEventCount(), 3, "Should successfully delete one event");
timeline.CancelScheduledValues(0.12f);
timeline.CancelScheduledValues(0.12);
is(timeline.GetEventCount(), 1, "Should successfully delete two events");
}
@ -233,7 +233,7 @@ void TestBeforeFirstEvent()
ErrorResultMock rv;
timeline.SetValueAtTime(20.0f, 1.0f, rv);
timeline.SetValueAtTime(20.0f, 1.0, rv);
is(timeline.GetValueAtTime(0.5f), 10.0f, "Retrun the default value before the first event");
}
@ -243,7 +243,7 @@ void TestAfterLastValueEvent()
ErrorResultMock rv;
timeline.SetValueAtTime(20.0f, 1.0f, rv);
timeline.SetValueAtTime(20.0f, 1.0, rv);
is(timeline.GetValueAtTime(1.5f), 20.0f, "Return the last value after the last SetValue event");
}
@ -253,7 +253,7 @@ void TestAfterLastTargetValueEvent()
ErrorResultMock rv;
timeline.SetTargetAtTime(20.0f, 1.0f, 5.0f, rv);
timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv);
is(timeline.GetValueAtTime(10.f), (20.f + (10.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after the last SetTarget event based on the curve");
}
@ -264,7 +264,7 @@ void TestAfterLastTargetValueEventWithValueSet()
ErrorResultMock rv;
timeline.SetValue(50.f);
timeline.SetTargetAtTime(20.0f, 1.0f, 5.0f, rv);
timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv);
is(timeline.GetValueAtTime(10.f), (20.f + (50.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after SetValue and the last SetTarget event based on the curve");
}
@ -277,7 +277,7 @@ void TestValue()
is(timeline.Value(), 10.0f, "value should initially match the default value");
timeline.SetValue(20.0f);
is(timeline.Value(), 20.0f, "Should be able to set the value");
timeline.SetValueAtTime(20.0f, 1.0f, rv);
timeline.SetValueAtTime(20.0f, 1.0, rv);
// TODO: The following check needs to change when we compute the value based on the current time of the context
is(timeline.Value(), 20.0f, "TODO...");
timeline.SetValue(30.0f);
@ -290,7 +290,7 @@ void TestLinearRampAtZero()
ErrorResultMock rv;
timeline.LinearRampToValueAtTime(20.0f, 0.0f, rv);
timeline.LinearRampToValueAtTime(20.0f, 0.0, rv);
is(timeline.GetValueAtTime(0.0f), 20.0f, "Should get the correct value when t0 == t1 == 0");
}
@ -300,7 +300,7 @@ void TestExponentialRampAtZero()
ErrorResultMock rv;
timeline.ExponentialRampToValueAtTime(20.0f, 0.0f, rv);
timeline.ExponentialRampToValueAtTime(20.0f, 0.0, rv);
is(timeline.GetValueAtTime(0.0f), 20.0f, "Should get the correct value when t0 == t1 == 0");
}
@ -310,8 +310,8 @@ void TestLinearRampAtSameTime()
ErrorResultMock rv;
timeline.SetValueAtTime(5.0f, 1.0f, rv);
timeline.LinearRampToValueAtTime(20.0f, 1.0f, rv);
timeline.SetValueAtTime(5.0f, 1.0, rv);
timeline.LinearRampToValueAtTime(20.0f, 1.0, rv);
is(timeline.GetValueAtTime(1.0f), 20.0f, "Should get the correct value when t0 == t1");
}
@ -321,8 +321,8 @@ void TestExponentialRampAtSameTime()
ErrorResultMock rv;
timeline.SetValueAtTime(5.0f, 1.0f, rv);
timeline.ExponentialRampToValueAtTime(20.0f, 1.0f, rv);
timeline.SetValueAtTime(5.0f, 1.0, rv);
timeline.ExponentialRampToValueAtTime(20.0f, 1.0, rv);
is(timeline.GetValueAtTime(1.0f), 20.0f, "Should get the correct value when t0 == t1");
}
@ -332,7 +332,7 @@ void TestSetTargetZeroTimeConstant()
ErrorResultMock rv;
timeline.SetTargetAtTime(20.0f, 1.0f, 0.0f, rv);
timeline.SetTargetAtTime(20.0f, 1.0, 0.0, rv);
is(timeline.GetValueAtTime(10.f), 20.f, "Should get the correct value with timeConstant == 0");
}

View File

@ -17,7 +17,7 @@ interface AudioBuffer {
readonly attribute long length;
// in seconds
readonly attribute float duration;
readonly attribute double duration;
readonly attribute long numberOfChannels;

View File

@ -28,10 +28,10 @@ interface mozAudioContext {
[Creator]
GainNode createGain();
// maxDelayTime should ideally be a restricted float to protect against
// maxDelayTime should ideally be a restricted double to protect against
// things such as NaNs.
[Creator, Throws]
DelayNode createDelay(optional float maxDelayTime = 1);
DelayNode createDelay(optional double maxDelayTime = 1);
[Creator]
BiquadFilterNode createBiquadFilter();
[Creator]

View File

@ -21,23 +21,23 @@ interface AudioParam {
// Parameter automation.
[Throws]
void setValueAtTime(float value, float startTime);
void setValueAtTime(float value, double startTime);
[Throws]
void linearRampToValueAtTime(float value, float endTime);
void linearRampToValueAtTime(float value, double endTime);
[Throws]
void exponentialRampToValueAtTime(float value, float endTime);
void exponentialRampToValueAtTime(float value, double endTime);
// Exponentially approach the target value with a rate having the given time constant.
[Throws]
void setTargetAtTime(float target, float startTime, float timeConstant);
void 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, float startTime, float duration);
// void setValueCurveAtTime(Float32Array values, double startTime, double duration);
// Cancels all scheduled parameter changes with times greater than or equal to startTime.
void cancelScheduledValues(float startTime);
void cancelScheduledValues(double startTime);
};