1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/webaudio/AudioContext.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,280 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef AudioContext_h_ 1.11 +#define AudioContext_h_ 1.12 + 1.13 +#include "mozilla/dom/AudioChannelBinding.h" 1.14 +#include "MediaBufferDecoder.h" 1.15 +#include "mozilla/Attributes.h" 1.16 +#include "mozilla/DOMEventTargetHelper.h" 1.17 +#include "mozilla/MemoryReporting.h" 1.18 +#include "mozilla/dom/TypedArray.h" 1.19 +#include "nsAutoPtr.h" 1.20 +#include "nsCOMPtr.h" 1.21 +#include "nsCycleCollectionParticipant.h" 1.22 +#include "nsHashKeys.h" 1.23 +#include "nsTHashtable.h" 1.24 +#include "js/TypeDecls.h" 1.25 +#include "nsIMemoryReporter.h" 1.26 + 1.27 +// X11 has a #define for CurrentTime. Unbelievable :-(. 1.28 +// See content/media/DOMMediaStream.h for more fun! 1.29 +#ifdef CurrentTime 1.30 +#undef CurrentTime 1.31 +#endif 1.32 + 1.33 +class nsPIDOMWindow; 1.34 + 1.35 +namespace mozilla { 1.36 + 1.37 +class DOMMediaStream; 1.38 +class ErrorResult; 1.39 +class MediaStream; 1.40 +class MediaStreamGraph; 1.41 + 1.42 +namespace dom { 1.43 + 1.44 +class AnalyserNode; 1.45 +class AudioBuffer; 1.46 +class AudioBufferSourceNode; 1.47 +class AudioDestinationNode; 1.48 +class AudioListener; 1.49 +class AudioNode; 1.50 +class BiquadFilterNode; 1.51 +class ChannelMergerNode; 1.52 +class ChannelSplitterNode; 1.53 +class ConvolverNode; 1.54 +class DelayNode; 1.55 +class DynamicsCompressorNode; 1.56 +class GainNode; 1.57 +class HTMLMediaElement; 1.58 +class MediaElementAudioSourceNode; 1.59 +class GlobalObject; 1.60 +class MediaStreamAudioDestinationNode; 1.61 +class MediaStreamAudioSourceNode; 1.62 +class OscillatorNode; 1.63 +class PannerNode; 1.64 +class ScriptProcessorNode; 1.65 +class WaveShaperNode; 1.66 +class PeriodicWave; 1.67 + 1.68 +class AudioContext MOZ_FINAL : public DOMEventTargetHelper, 1.69 + public nsIMemoryReporter 1.70 +{ 1.71 + AudioContext(nsPIDOMWindow* aParentWindow, 1.72 + bool aIsOffline, 1.73 + AudioChannel aChannel = AudioChannel::Normal, 1.74 + uint32_t aNumberOfChannels = 0, 1.75 + uint32_t aLength = 0, 1.76 + float aSampleRate = 0.0f); 1.77 + ~AudioContext(); 1.78 + 1.79 +public: 1.80 + NS_DECL_ISUPPORTS_INHERITED 1.81 + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioContext, 1.82 + DOMEventTargetHelper) 1.83 + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) 1.84 + 1.85 + nsPIDOMWindow* GetParentObject() const 1.86 + { 1.87 + return GetOwner(); 1.88 + } 1.89 + 1.90 + void Shutdown(); // idempotent 1.91 + void Suspend(); 1.92 + void Resume(); 1.93 + 1.94 + virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE; 1.95 + 1.96 + using DOMEventTargetHelper::DispatchTrustedEvent; 1.97 + 1.98 + // Constructor for regular AudioContext 1.99 + static already_AddRefed<AudioContext> 1.100 + Constructor(const GlobalObject& aGlobal, ErrorResult& aRv); 1.101 + 1.102 + // Constructor for regular AudioContext. A default audio channel is needed. 1.103 + static already_AddRefed<AudioContext> 1.104 + Constructor(const GlobalObject& aGlobal, 1.105 + AudioChannel aChannel, 1.106 + ErrorResult& aRv); 1.107 + 1.108 + // Constructor for offline AudioContext 1.109 + static already_AddRefed<AudioContext> 1.110 + Constructor(const GlobalObject& aGlobal, 1.111 + uint32_t aNumberOfChannels, 1.112 + uint32_t aLength, 1.113 + float aSampleRate, 1.114 + ErrorResult& aRv); 1.115 + 1.116 + // AudioContext methods 1.117 + 1.118 + AudioDestinationNode* Destination() const 1.119 + { 1.120 + return mDestination; 1.121 + } 1.122 + 1.123 + float SampleRate() const 1.124 + { 1.125 + return mSampleRate; 1.126 + } 1.127 + 1.128 + double CurrentTime() const; 1.129 + 1.130 + AudioListener* Listener(); 1.131 + 1.132 + already_AddRefed<AudioBufferSourceNode> CreateBufferSource(); 1.133 + 1.134 + already_AddRefed<AudioBuffer> 1.135 + CreateBuffer(JSContext* aJSContext, uint32_t aNumberOfChannels, 1.136 + uint32_t aLength, float aSampleRate, 1.137 + ErrorResult& aRv); 1.138 + 1.139 + already_AddRefed<MediaStreamAudioDestinationNode> 1.140 + CreateMediaStreamDestination(ErrorResult& aRv); 1.141 + 1.142 + already_AddRefed<ScriptProcessorNode> 1.143 + CreateScriptProcessor(uint32_t aBufferSize, 1.144 + uint32_t aNumberOfInputChannels, 1.145 + uint32_t aNumberOfOutputChannels, 1.146 + ErrorResult& aRv); 1.147 + 1.148 + already_AddRefed<AnalyserNode> 1.149 + CreateAnalyser(); 1.150 + 1.151 + already_AddRefed<GainNode> 1.152 + CreateGain(); 1.153 + 1.154 + already_AddRefed<WaveShaperNode> 1.155 + CreateWaveShaper(); 1.156 + 1.157 + already_AddRefed<MediaElementAudioSourceNode> 1.158 + CreateMediaElementSource(HTMLMediaElement& aMediaElement, ErrorResult& aRv); 1.159 + already_AddRefed<MediaStreamAudioSourceNode> 1.160 + CreateMediaStreamSource(DOMMediaStream& aMediaStream, ErrorResult& aRv); 1.161 + 1.162 + already_AddRefed<DelayNode> 1.163 + CreateDelay(double aMaxDelayTime, ErrorResult& aRv); 1.164 + 1.165 + already_AddRefed<PannerNode> 1.166 + CreatePanner(); 1.167 + 1.168 + already_AddRefed<ConvolverNode> 1.169 + CreateConvolver(); 1.170 + 1.171 + already_AddRefed<ChannelSplitterNode> 1.172 + CreateChannelSplitter(uint32_t aNumberOfOutputs, ErrorResult& aRv); 1.173 + 1.174 + already_AddRefed<ChannelMergerNode> 1.175 + CreateChannelMerger(uint32_t aNumberOfInputs, ErrorResult& aRv); 1.176 + 1.177 + already_AddRefed<DynamicsCompressorNode> 1.178 + CreateDynamicsCompressor(); 1.179 + 1.180 + already_AddRefed<BiquadFilterNode> 1.181 + CreateBiquadFilter(); 1.182 + 1.183 + already_AddRefed<OscillatorNode> 1.184 + CreateOscillator(); 1.185 + 1.186 + already_AddRefed<PeriodicWave> 1.187 + CreatePeriodicWave(const Float32Array& aRealData, const Float32Array& aImagData, 1.188 + ErrorResult& aRv); 1.189 + 1.190 + void DecodeAudioData(const ArrayBuffer& aBuffer, 1.191 + DecodeSuccessCallback& aSuccessCallback, 1.192 + const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback); 1.193 + 1.194 + // OfflineAudioContext methods 1.195 + void StartRendering(ErrorResult& aRv); 1.196 + IMPL_EVENT_HANDLER(complete) 1.197 + 1.198 + bool IsOffline() const { return mIsOffline; } 1.199 + 1.200 + MediaStreamGraph* Graph() const; 1.201 + MediaStream* DestinationStream() const; 1.202 + 1.203 + // Nodes register here if they will produce sound even if they have silent 1.204 + // or no input connections. The AudioContext will keep registered nodes 1.205 + // alive until the context is collected. This takes care of "playing" 1.206 + // references and "tail-time" references. 1.207 + void RegisterActiveNode(AudioNode* aNode); 1.208 + // Nodes unregister when they have finished producing sound for the 1.209 + // foreseeable future. 1.210 + // Do NOT call UnregisterActiveNode from an AudioNode destructor. 1.211 + // If the destructor is called, then the Node has already been unregistered. 1.212 + // The destructor may be called during hashtable enumeration, during which 1.213 + // unregistering would not be safe. 1.214 + void UnregisterActiveNode(AudioNode* aNode); 1.215 + 1.216 + void UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode); 1.217 + void UnregisterPannerNode(PannerNode* aNode); 1.218 + void UpdatePannerSource(); 1.219 + 1.220 + uint32_t MaxChannelCount() const; 1.221 + 1.222 + void Mute() const; 1.223 + void Unmute() const; 1.224 + 1.225 + JSContext* GetJSContext() const; 1.226 + 1.227 + AudioChannel MozAudioChannelType() const; 1.228 + void SetMozAudioChannelType(AudioChannel aValue, ErrorResult& aRv); 1.229 + 1.230 + void UpdateNodeCount(int32_t aDelta); 1.231 + 1.232 + double DOMTimeToStreamTime(double aTime) const 1.233 + { 1.234 + return aTime - ExtraCurrentTime(); 1.235 + } 1.236 + 1.237 +private: 1.238 + /** 1.239 + * Returns the amount of extra time added to the current time of the 1.240 + * AudioDestinationNode's MediaStream to get this AudioContext's currentTime. 1.241 + * Must be subtracted from all DOM API parameter times that are on the same 1.242 + * timeline as AudioContext's currentTime to get times we can pass to the 1.243 + * MediaStreamGraph. 1.244 + */ 1.245 + double ExtraCurrentTime() const; 1.246 + 1.247 + void RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob); 1.248 + void ShutdownDecoder(); 1.249 + 1.250 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; 1.251 + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, 1.252 + nsISupports* aData); 1.253 + 1.254 + friend struct ::mozilla::WebAudioDecodeJob; 1.255 + 1.256 +private: 1.257 + // Note that it's important for mSampleRate to be initialized before 1.258 + // mDestination, as mDestination's constructor needs to access it! 1.259 + const float mSampleRate; 1.260 + nsRefPtr<AudioDestinationNode> mDestination; 1.261 + nsRefPtr<AudioListener> mListener; 1.262 + MediaBufferDecoder mDecoder; 1.263 + nsTArray<nsRefPtr<WebAudioDecodeJob> > mDecodeJobs; 1.264 + // See RegisterActiveNode. These will keep the AudioContext alive while it 1.265 + // is rendering and the window remains alive. 1.266 + nsTHashtable<nsRefPtrHashKey<AudioNode> > mActiveNodes; 1.267 + // Hashsets containing all the PannerNodes, to compute the doppler shift. 1.268 + // These are weak pointers. 1.269 + nsTHashtable<nsPtrHashKey<PannerNode> > mPannerNodes; 1.270 + // Number of channels passed in the OfflineAudioContext ctor. 1.271 + uint32_t mNumberOfChannels; 1.272 + // Number of nodes that currently exist for this AudioContext 1.273 + int32_t mNodeCount; 1.274 + bool mIsOffline; 1.275 + bool mIsStarted; 1.276 + bool mIsShutDown; 1.277 +}; 1.278 + 1.279 +} 1.280 +} 1.281 + 1.282 +#endif 1.283 +