michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef AudioParam_h_ michael@0: #define AudioParam_h_ michael@0: michael@0: #include "AudioParamTimeline.h" michael@0: #include "nsWrapperCache.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "AudioNode.h" michael@0: #include "mozilla/dom/TypedArray.h" michael@0: #include "WebAudioUtils.h" michael@0: #include "js/TypeDecls.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: namespace dom { michael@0: michael@0: class AudioParam MOZ_FINAL : public nsWrapperCache, michael@0: public AudioParamTimeline michael@0: { michael@0: public: michael@0: typedef void (*CallbackType)(AudioNode*); michael@0: michael@0: AudioParam(AudioNode* aNode, michael@0: CallbackType aCallback, michael@0: float aDefaultValue); michael@0: virtual ~AudioParam(); michael@0: michael@0: NS_IMETHOD_(MozExternalRefCountType) AddRef(void); michael@0: NS_IMETHOD_(MozExternalRefCountType) Release(void); michael@0: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioParam) michael@0: michael@0: AudioContext* GetParentObject() const michael@0: { michael@0: return mNode->Context(); michael@0: } michael@0: michael@0: double DOMTimeToStreamTime(double aTime) const michael@0: { michael@0: return mNode->Context()->DOMTimeToStreamTime(aTime); michael@0: } michael@0: michael@0: virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; michael@0: michael@0: // We override SetValueCurveAtTime to convert the Float32Array to the wrapper michael@0: // object. michael@0: void SetValueCurveAtTime(const Float32Array& aValues, double aStartTime, double aDuration, ErrorResult& aRv) michael@0: { michael@0: if (!WebAudioUtils::IsTimeValid(aStartTime)) { michael@0: aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); michael@0: return; michael@0: } michael@0: aValues.ComputeLengthAndData(); michael@0: AudioParamTimeline::SetValueCurveAtTime(aValues.Data(), aValues.Length(), michael@0: DOMTimeToStreamTime(aStartTime), aDuration, aRv); michael@0: mCallback(mNode); michael@0: } michael@0: michael@0: // We override the rest of the mutating AudioParamTimeline methods in order to make michael@0: // sure that the callback is called every time that this object gets mutated. michael@0: void SetValue(float aValue) michael@0: { michael@0: // Optimize away setting the same value on an AudioParam michael@0: if (HasSimpleValue() && michael@0: WebAudioUtils::FuzzyEqual(GetValue(), aValue)) { michael@0: return; michael@0: } michael@0: AudioParamTimeline::SetValue(aValue); michael@0: mCallback(mNode); michael@0: } michael@0: void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv) michael@0: { michael@0: if (!WebAudioUtils::IsTimeValid(aStartTime)) { michael@0: aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); michael@0: return; michael@0: } michael@0: AudioParamTimeline::SetValueAtTime(aValue, DOMTimeToStreamTime(aStartTime), aRv); michael@0: mCallback(mNode); michael@0: } michael@0: void LinearRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv) michael@0: { michael@0: if (!WebAudioUtils::IsTimeValid(aEndTime)) { michael@0: aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); michael@0: return; michael@0: } michael@0: AudioParamTimeline::LinearRampToValueAtTime(aValue, DOMTimeToStreamTime(aEndTime), aRv); michael@0: mCallback(mNode); michael@0: } michael@0: void ExponentialRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv) michael@0: { michael@0: if (!WebAudioUtils::IsTimeValid(aEndTime)) { michael@0: aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); michael@0: return; michael@0: } michael@0: AudioParamTimeline::ExponentialRampToValueAtTime(aValue, DOMTimeToStreamTime(aEndTime), aRv); michael@0: mCallback(mNode); michael@0: } michael@0: void SetTargetAtTime(float aTarget, double aStartTime, double aTimeConstant, ErrorResult& aRv) michael@0: { michael@0: if (!WebAudioUtils::IsTimeValid(aStartTime) || michael@0: !WebAudioUtils::IsTimeValid(aTimeConstant)) { michael@0: aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); michael@0: return; michael@0: } michael@0: AudioParamTimeline::SetTargetAtTime(aTarget, DOMTimeToStreamTime(aStartTime), aTimeConstant, aRv); michael@0: mCallback(mNode); michael@0: } michael@0: void CancelScheduledValues(double aStartTime, ErrorResult& aRv) michael@0: { michael@0: if (!WebAudioUtils::IsTimeValid(aStartTime)) { michael@0: aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR); michael@0: return; michael@0: } michael@0: AudioParamTimeline::CancelScheduledValues(DOMTimeToStreamTime(aStartTime)); michael@0: mCallback(mNode); michael@0: } michael@0: michael@0: float DefaultValue() const michael@0: { michael@0: return mDefaultValue; michael@0: } michael@0: michael@0: AudioNode* Node() const michael@0: { michael@0: return mNode; michael@0: } michael@0: michael@0: const nsTArray& InputNodes() const michael@0: { michael@0: return mInputNodes; michael@0: } michael@0: michael@0: void RemoveInputNode(uint32_t aIndex) michael@0: { michael@0: mInputNodes.RemoveElementAt(aIndex); michael@0: } michael@0: michael@0: AudioNode::InputNode* AppendInputNode() michael@0: { michael@0: return mInputNodes.AppendElement(); michael@0: } michael@0: michael@0: void DisconnectFromGraphAndDestroyStream(); michael@0: michael@0: // May create the stream if it doesn't exist michael@0: MediaStream* Stream(); michael@0: michael@0: virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE michael@0: { michael@0: size_t amount = AudioParamTimeline::SizeOfExcludingThis(aMallocSizeOf); michael@0: // Not owned: michael@0: // - mNode michael@0: michael@0: // Just count the array, actual nodes are counted in mNode. michael@0: amount += mInputNodes.SizeOfExcludingThis(aMallocSizeOf); michael@0: michael@0: if (mNodeStreamPort) { michael@0: amount += mNodeStreamPort->SizeOfIncludingThis(aMallocSizeOf); michael@0: } michael@0: michael@0: return amount; michael@0: } michael@0: michael@0: virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE michael@0: { michael@0: return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); michael@0: } michael@0: michael@0: protected: michael@0: nsCycleCollectingAutoRefCnt mRefCnt; michael@0: NS_DECL_OWNINGTHREAD michael@0: michael@0: private: michael@0: nsRefPtr mNode; michael@0: // For every InputNode, there is a corresponding entry in mOutputParams of the michael@0: // InputNode's mInputNode. michael@0: nsTArray mInputNodes; michael@0: CallbackType mCallback; michael@0: const float mDefaultValue; michael@0: // The input port used to connect the AudioParam's stream to its node's stream michael@0: nsRefPtr mNodeStreamPort; michael@0: }; michael@0: michael@0: } michael@0: } michael@0: michael@0: #endif michael@0: