Fri, 16 Jan 2015 04:50:19 +0100
Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim:set ts=2 sw=2 sts=2 et cindent: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #ifndef AudioContext_h_ |
michael@0 | 8 | #define AudioContext_h_ |
michael@0 | 9 | |
michael@0 | 10 | #include "mozilla/dom/AudioChannelBinding.h" |
michael@0 | 11 | #include "MediaBufferDecoder.h" |
michael@0 | 12 | #include "mozilla/Attributes.h" |
michael@0 | 13 | #include "mozilla/DOMEventTargetHelper.h" |
michael@0 | 14 | #include "mozilla/MemoryReporting.h" |
michael@0 | 15 | #include "mozilla/dom/TypedArray.h" |
michael@0 | 16 | #include "nsAutoPtr.h" |
michael@0 | 17 | #include "nsCOMPtr.h" |
michael@0 | 18 | #include "nsCycleCollectionParticipant.h" |
michael@0 | 19 | #include "nsHashKeys.h" |
michael@0 | 20 | #include "nsTHashtable.h" |
michael@0 | 21 | #include "js/TypeDecls.h" |
michael@0 | 22 | #include "nsIMemoryReporter.h" |
michael@0 | 23 | |
michael@0 | 24 | // X11 has a #define for CurrentTime. Unbelievable :-(. |
michael@0 | 25 | // See content/media/DOMMediaStream.h for more fun! |
michael@0 | 26 | #ifdef CurrentTime |
michael@0 | 27 | #undef CurrentTime |
michael@0 | 28 | #endif |
michael@0 | 29 | |
michael@0 | 30 | class nsPIDOMWindow; |
michael@0 | 31 | |
michael@0 | 32 | namespace mozilla { |
michael@0 | 33 | |
michael@0 | 34 | class DOMMediaStream; |
michael@0 | 35 | class ErrorResult; |
michael@0 | 36 | class MediaStream; |
michael@0 | 37 | class MediaStreamGraph; |
michael@0 | 38 | |
michael@0 | 39 | namespace dom { |
michael@0 | 40 | |
michael@0 | 41 | class AnalyserNode; |
michael@0 | 42 | class AudioBuffer; |
michael@0 | 43 | class AudioBufferSourceNode; |
michael@0 | 44 | class AudioDestinationNode; |
michael@0 | 45 | class AudioListener; |
michael@0 | 46 | class AudioNode; |
michael@0 | 47 | class BiquadFilterNode; |
michael@0 | 48 | class ChannelMergerNode; |
michael@0 | 49 | class ChannelSplitterNode; |
michael@0 | 50 | class ConvolverNode; |
michael@0 | 51 | class DelayNode; |
michael@0 | 52 | class DynamicsCompressorNode; |
michael@0 | 53 | class GainNode; |
michael@0 | 54 | class HTMLMediaElement; |
michael@0 | 55 | class MediaElementAudioSourceNode; |
michael@0 | 56 | class GlobalObject; |
michael@0 | 57 | class MediaStreamAudioDestinationNode; |
michael@0 | 58 | class MediaStreamAudioSourceNode; |
michael@0 | 59 | class OscillatorNode; |
michael@0 | 60 | class PannerNode; |
michael@0 | 61 | class ScriptProcessorNode; |
michael@0 | 62 | class WaveShaperNode; |
michael@0 | 63 | class PeriodicWave; |
michael@0 | 64 | |
michael@0 | 65 | class AudioContext MOZ_FINAL : public DOMEventTargetHelper, |
michael@0 | 66 | public nsIMemoryReporter |
michael@0 | 67 | { |
michael@0 | 68 | AudioContext(nsPIDOMWindow* aParentWindow, |
michael@0 | 69 | bool aIsOffline, |
michael@0 | 70 | AudioChannel aChannel = AudioChannel::Normal, |
michael@0 | 71 | uint32_t aNumberOfChannels = 0, |
michael@0 | 72 | uint32_t aLength = 0, |
michael@0 | 73 | float aSampleRate = 0.0f); |
michael@0 | 74 | ~AudioContext(); |
michael@0 | 75 | |
michael@0 | 76 | public: |
michael@0 | 77 | NS_DECL_ISUPPORTS_INHERITED |
michael@0 | 78 | NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioContext, |
michael@0 | 79 | DOMEventTargetHelper) |
michael@0 | 80 | MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) |
michael@0 | 81 | |
michael@0 | 82 | nsPIDOMWindow* GetParentObject() const |
michael@0 | 83 | { |
michael@0 | 84 | return GetOwner(); |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | void Shutdown(); // idempotent |
michael@0 | 88 | void Suspend(); |
michael@0 | 89 | void Resume(); |
michael@0 | 90 | |
michael@0 | 91 | virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; |
michael@0 | 92 | |
michael@0 | 93 | using DOMEventTargetHelper::DispatchTrustedEvent; |
michael@0 | 94 | |
michael@0 | 95 | // Constructor for regular AudioContext |
michael@0 | 96 | static already_AddRefed<AudioContext> |
michael@0 | 97 | Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); |
michael@0 | 98 | |
michael@0 | 99 | // Constructor for regular AudioContext. A default audio channel is needed. |
michael@0 | 100 | static already_AddRefed<AudioContext> |
michael@0 | 101 | Constructor(const GlobalObject& aGlobal, |
michael@0 | 102 | AudioChannel aChannel, |
michael@0 | 103 | ErrorResult& aRv); |
michael@0 | 104 | |
michael@0 | 105 | // Constructor for offline AudioContext |
michael@0 | 106 | static already_AddRefed<AudioContext> |
michael@0 | 107 | Constructor(const GlobalObject& aGlobal, |
michael@0 | 108 | uint32_t aNumberOfChannels, |
michael@0 | 109 | uint32_t aLength, |
michael@0 | 110 | float aSampleRate, |
michael@0 | 111 | ErrorResult& aRv); |
michael@0 | 112 | |
michael@0 | 113 | // AudioContext methods |
michael@0 | 114 | |
michael@0 | 115 | AudioDestinationNode* Destination() const |
michael@0 | 116 | { |
michael@0 | 117 | return mDestination; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | float SampleRate() const |
michael@0 | 121 | { |
michael@0 | 122 | return mSampleRate; |
michael@0 | 123 | } |
michael@0 | 124 | |
michael@0 | 125 | double CurrentTime() const; |
michael@0 | 126 | |
michael@0 | 127 | AudioListener* Listener(); |
michael@0 | 128 | |
michael@0 | 129 | already_AddRefed<AudioBufferSourceNode> CreateBufferSource(); |
michael@0 | 130 | |
michael@0 | 131 | already_AddRefed<AudioBuffer> |
michael@0 | 132 | CreateBuffer(JSContext* aJSContext, uint32_t aNumberOfChannels, |
michael@0 | 133 | uint32_t aLength, float aSampleRate, |
michael@0 | 134 | ErrorResult& aRv); |
michael@0 | 135 | |
michael@0 | 136 | already_AddRefed<MediaStreamAudioDestinationNode> |
michael@0 | 137 | CreateMediaStreamDestination(ErrorResult& aRv); |
michael@0 | 138 | |
michael@0 | 139 | already_AddRefed<ScriptProcessorNode> |
michael@0 | 140 | CreateScriptProcessor(uint32_t aBufferSize, |
michael@0 | 141 | uint32_t aNumberOfInputChannels, |
michael@0 | 142 | uint32_t aNumberOfOutputChannels, |
michael@0 | 143 | ErrorResult& aRv); |
michael@0 | 144 | |
michael@0 | 145 | already_AddRefed<AnalyserNode> |
michael@0 | 146 | CreateAnalyser(); |
michael@0 | 147 | |
michael@0 | 148 | already_AddRefed<GainNode> |
michael@0 | 149 | CreateGain(); |
michael@0 | 150 | |
michael@0 | 151 | already_AddRefed<WaveShaperNode> |
michael@0 | 152 | CreateWaveShaper(); |
michael@0 | 153 | |
michael@0 | 154 | already_AddRefed<MediaElementAudioSourceNode> |
michael@0 | 155 | CreateMediaElementSource(HTMLMediaElement& aMediaElement, ErrorResult& aRv); |
michael@0 | 156 | already_AddRefed<MediaStreamAudioSourceNode> |
michael@0 | 157 | CreateMediaStreamSource(DOMMediaStream& aMediaStream, ErrorResult& aRv); |
michael@0 | 158 | |
michael@0 | 159 | already_AddRefed<DelayNode> |
michael@0 | 160 | CreateDelay(double aMaxDelayTime, ErrorResult& aRv); |
michael@0 | 161 | |
michael@0 | 162 | already_AddRefed<PannerNode> |
michael@0 | 163 | CreatePanner(); |
michael@0 | 164 | |
michael@0 | 165 | already_AddRefed<ConvolverNode> |
michael@0 | 166 | CreateConvolver(); |
michael@0 | 167 | |
michael@0 | 168 | already_AddRefed<ChannelSplitterNode> |
michael@0 | 169 | CreateChannelSplitter(uint32_t aNumberOfOutputs, ErrorResult& aRv); |
michael@0 | 170 | |
michael@0 | 171 | already_AddRefed<ChannelMergerNode> |
michael@0 | 172 | CreateChannelMerger(uint32_t aNumberOfInputs, ErrorResult& aRv); |
michael@0 | 173 | |
michael@0 | 174 | already_AddRefed<DynamicsCompressorNode> |
michael@0 | 175 | CreateDynamicsCompressor(); |
michael@0 | 176 | |
michael@0 | 177 | already_AddRefed<BiquadFilterNode> |
michael@0 | 178 | CreateBiquadFilter(); |
michael@0 | 179 | |
michael@0 | 180 | already_AddRefed<OscillatorNode> |
michael@0 | 181 | CreateOscillator(); |
michael@0 | 182 | |
michael@0 | 183 | already_AddRefed<PeriodicWave> |
michael@0 | 184 | CreatePeriodicWave(const Float32Array& aRealData, const Float32Array& aImagData, |
michael@0 | 185 | ErrorResult& aRv); |
michael@0 | 186 | |
michael@0 | 187 | void DecodeAudioData(const ArrayBuffer& aBuffer, |
michael@0 | 188 | DecodeSuccessCallback& aSuccessCallback, |
michael@0 | 189 | const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback); |
michael@0 | 190 | |
michael@0 | 191 | // OfflineAudioContext methods |
michael@0 | 192 | void StartRendering(ErrorResult& aRv); |
michael@0 | 193 | IMPL_EVENT_HANDLER(complete) |
michael@0 | 194 | |
michael@0 | 195 | bool IsOffline() const { return mIsOffline; } |
michael@0 | 196 | |
michael@0 | 197 | MediaStreamGraph* Graph() const; |
michael@0 | 198 | MediaStream* DestinationStream() const; |
michael@0 | 199 | |
michael@0 | 200 | // Nodes register here if they will produce sound even if they have silent |
michael@0 | 201 | // or no input connections. The AudioContext will keep registered nodes |
michael@0 | 202 | // alive until the context is collected. This takes care of "playing" |
michael@0 | 203 | // references and "tail-time" references. |
michael@0 | 204 | void RegisterActiveNode(AudioNode* aNode); |
michael@0 | 205 | // Nodes unregister when they have finished producing sound for the |
michael@0 | 206 | // foreseeable future. |
michael@0 | 207 | // Do NOT call UnregisterActiveNode from an AudioNode destructor. |
michael@0 | 208 | // If the destructor is called, then the Node has already been unregistered. |
michael@0 | 209 | // The destructor may be called during hashtable enumeration, during which |
michael@0 | 210 | // unregistering would not be safe. |
michael@0 | 211 | void UnregisterActiveNode(AudioNode* aNode); |
michael@0 | 212 | |
michael@0 | 213 | void UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode); |
michael@0 | 214 | void UnregisterPannerNode(PannerNode* aNode); |
michael@0 | 215 | void UpdatePannerSource(); |
michael@0 | 216 | |
michael@0 | 217 | uint32_t MaxChannelCount() const; |
michael@0 | 218 | |
michael@0 | 219 | void Mute() const; |
michael@0 | 220 | void Unmute() const; |
michael@0 | 221 | |
michael@0 | 222 | JSContext* GetJSContext() const; |
michael@0 | 223 | |
michael@0 | 224 | AudioChannel MozAudioChannelType() const; |
michael@0 | 225 | void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv); |
michael@0 | 226 | |
michael@0 | 227 | void UpdateNodeCount(int32_t aDelta); |
michael@0 | 228 | |
michael@0 | 229 | double DOMTimeToStreamTime(double aTime) const |
michael@0 | 230 | { |
michael@0 | 231 | return aTime - ExtraCurrentTime(); |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | private: |
michael@0 | 235 | /** |
michael@0 | 236 | * Returns the amount of extra time added to the current time of the |
michael@0 | 237 | * AudioDestinationNode's MediaStream to get this AudioContext's currentTime. |
michael@0 | 238 | * Must be subtracted from all DOM API parameter times that are on the same |
michael@0 | 239 | * timeline as AudioContext's currentTime to get times we can pass to the |
michael@0 | 240 | * MediaStreamGraph. |
michael@0 | 241 | */ |
michael@0 | 242 | double ExtraCurrentTime() const; |
michael@0 | 243 | |
michael@0 | 244 | void RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob); |
michael@0 | 245 | void ShutdownDecoder(); |
michael@0 | 246 | |
michael@0 | 247 | size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; |
michael@0 | 248 | NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, |
michael@0 | 249 | nsISupports* aData); |
michael@0 | 250 | |
michael@0 | 251 | friend struct ::mozilla::WebAudioDecodeJob; |
michael@0 | 252 | |
michael@0 | 253 | private: |
michael@0 | 254 | // Note that it's important for mSampleRate to be initialized before |
michael@0 | 255 | // mDestination, as mDestination's constructor needs to access it! |
michael@0 | 256 | const float mSampleRate; |
michael@0 | 257 | nsRefPtr<AudioDestinationNode> mDestination; |
michael@0 | 258 | nsRefPtr<AudioListener> mListener; |
michael@0 | 259 | MediaBufferDecoder mDecoder; |
michael@0 | 260 | nsTArray<nsRefPtr<WebAudioDecodeJob> > mDecodeJobs; |
michael@0 | 261 | // See RegisterActiveNode. These will keep the AudioContext alive while it |
michael@0 | 262 | // is rendering and the window remains alive. |
michael@0 | 263 | nsTHashtable<nsRefPtrHashKey<AudioNode> > mActiveNodes; |
michael@0 | 264 | // Hashsets containing all the PannerNodes, to compute the doppler shift. |
michael@0 | 265 | // These are weak pointers. |
michael@0 | 266 | nsTHashtable<nsPtrHashKey<PannerNode> > mPannerNodes; |
michael@0 | 267 | // Number of channels passed in the OfflineAudioContext ctor. |
michael@0 | 268 | uint32_t mNumberOfChannels; |
michael@0 | 269 | // Number of nodes that currently exist for this AudioContext |
michael@0 | 270 | int32_t mNodeCount; |
michael@0 | 271 | bool mIsOffline; |
michael@0 | 272 | bool mIsStarted; |
michael@0 | 273 | bool mIsShutDown; |
michael@0 | 274 | }; |
michael@0 | 275 | |
michael@0 | 276 | } |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | #endif |
michael@0 | 280 |