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