|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef MOZILLA_AUDIONODESTREAM_H_ |
|
7 #define MOZILLA_AUDIONODESTREAM_H_ |
|
8 |
|
9 #include "MediaStreamGraph.h" |
|
10 #include "mozilla/dom/AudioNodeBinding.h" |
|
11 #include "AudioSegment.h" |
|
12 |
|
13 namespace mozilla { |
|
14 |
|
15 namespace dom { |
|
16 struct ThreeDPoint; |
|
17 class AudioParamTimeline; |
|
18 class DelayNodeEngine; |
|
19 class AudioContext; |
|
20 } |
|
21 |
|
22 class ThreadSharedFloatArrayBufferList; |
|
23 class AudioNodeEngine; |
|
24 |
|
25 /** |
|
26 * An AudioNodeStream produces one audio track with ID AUDIO_TRACK. |
|
27 * The start time of the AudioTrack is aligned to the start time of the |
|
28 * AudioContext's destination node stream, plus some multiple of BLOCK_SIZE |
|
29 * samples. |
|
30 * |
|
31 * An AudioNodeStream has an AudioNodeEngine plugged into it that does the |
|
32 * actual audio processing. AudioNodeStream contains the glue code that |
|
33 * integrates audio processing with the MediaStreamGraph. |
|
34 */ |
|
35 class AudioNodeStream : public ProcessedMediaStream { |
|
36 typedef dom::ChannelCountMode ChannelCountMode; |
|
37 typedef dom::ChannelInterpretation ChannelInterpretation; |
|
38 |
|
39 public: |
|
40 typedef mozilla::dom::AudioContext AudioContext; |
|
41 |
|
42 enum { AUDIO_TRACK = 1 }; |
|
43 |
|
44 typedef nsAutoTArray<AudioChunk, 1> OutputChunks; |
|
45 |
|
46 /** |
|
47 * Transfers ownership of aEngine to the new AudioNodeStream. |
|
48 */ |
|
49 AudioNodeStream(AudioNodeEngine* aEngine, |
|
50 MediaStreamGraph::AudioNodeStreamKind aKind, |
|
51 TrackRate aSampleRate) |
|
52 : ProcessedMediaStream(nullptr), |
|
53 mEngine(aEngine), |
|
54 mSampleRate(aSampleRate), |
|
55 mKind(aKind), |
|
56 mNumberOfInputChannels(2), |
|
57 mMarkAsFinishedAfterThisBlock(false), |
|
58 mAudioParamStream(false), |
|
59 mMuted(false) |
|
60 { |
|
61 MOZ_ASSERT(NS_IsMainThread()); |
|
62 mChannelCountMode = ChannelCountMode::Max; |
|
63 mChannelInterpretation = ChannelInterpretation::Speakers; |
|
64 // AudioNodes are always producing data |
|
65 mHasCurrentData = true; |
|
66 MOZ_COUNT_CTOR(AudioNodeStream); |
|
67 } |
|
68 ~AudioNodeStream(); |
|
69 |
|
70 // Control API |
|
71 /** |
|
72 * Sets a parameter that's a time relative to some stream's played time. |
|
73 * This time is converted to a time relative to this stream when it's set. |
|
74 */ |
|
75 void SetStreamTimeParameter(uint32_t aIndex, AudioContext* aContext, |
|
76 double aStreamTime); |
|
77 void SetDoubleParameter(uint32_t aIndex, double aValue); |
|
78 void SetInt32Parameter(uint32_t aIndex, int32_t aValue); |
|
79 void SetTimelineParameter(uint32_t aIndex, const dom::AudioParamTimeline& aValue); |
|
80 void SetThreeDPointParameter(uint32_t aIndex, const dom::ThreeDPoint& aValue); |
|
81 void SetBuffer(already_AddRefed<ThreadSharedFloatArrayBufferList>&& aBuffer); |
|
82 // This consumes the contents of aData. aData will be emptied after this returns. |
|
83 void SetRawArrayData(nsTArray<float>& aData); |
|
84 void SetChannelMixingParameters(uint32_t aNumberOfChannels, |
|
85 ChannelCountMode aChannelCountMoe, |
|
86 ChannelInterpretation aChannelInterpretation); |
|
87 ChannelInterpretation GetChannelInterpretation() |
|
88 { |
|
89 return mChannelInterpretation; |
|
90 } |
|
91 |
|
92 void SetAudioParamHelperStream() |
|
93 { |
|
94 MOZ_ASSERT(!mAudioParamStream, "Can only do this once"); |
|
95 mAudioParamStream = true; |
|
96 } |
|
97 |
|
98 virtual AudioNodeStream* AsAudioNodeStream() MOZ_OVERRIDE { return this; } |
|
99 |
|
100 // Graph thread only |
|
101 void SetStreamTimeParameterImpl(uint32_t aIndex, MediaStream* aRelativeToStream, |
|
102 double aStreamTime); |
|
103 void SetChannelMixingParametersImpl(uint32_t aNumberOfChannels, |
|
104 ChannelCountMode aChannelCountMoe, |
|
105 ChannelInterpretation aChannelInterpretation); |
|
106 virtual void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) MOZ_OVERRIDE; |
|
107 TrackTicks GetCurrentPosition(); |
|
108 bool IsAudioParamStream() const |
|
109 { |
|
110 return mAudioParamStream; |
|
111 } |
|
112 void Mute() { |
|
113 mMuted = true; |
|
114 } |
|
115 |
|
116 void Unmute() { |
|
117 mMuted = false; |
|
118 } |
|
119 |
|
120 const OutputChunks& LastChunks() const |
|
121 { |
|
122 return mLastChunks; |
|
123 } |
|
124 virtual bool MainThreadNeedsUpdates() const MOZ_OVERRIDE |
|
125 { |
|
126 // Only source and external streams need updates on the main thread. |
|
127 return (mKind == MediaStreamGraph::SOURCE_STREAM && mFinished) || |
|
128 mKind == MediaStreamGraph::EXTERNAL_STREAM; |
|
129 } |
|
130 virtual bool IsIntrinsicallyConsumed() const MOZ_OVERRIDE |
|
131 { |
|
132 return true; |
|
133 } |
|
134 |
|
135 // Any thread |
|
136 AudioNodeEngine* Engine() { return mEngine; } |
|
137 TrackRate SampleRate() const { return mSampleRate; } |
|
138 |
|
139 /** |
|
140 * Convert a time in seconds on the destination stream to seconds |
|
141 * on this stream. |
|
142 */ |
|
143 double TimeFromDestinationTime(AudioNodeStream* aDestination, |
|
144 double aSeconds); |
|
145 /** |
|
146 * Convert a time in seconds on the destination stream to TrackTicks |
|
147 * on this stream. |
|
148 */ |
|
149 TrackTicks TicksFromDestinationTime(MediaStream* aDestination, |
|
150 double aSeconds); |
|
151 /** |
|
152 * Get the destination stream time in seconds corresponding to a position on |
|
153 * this stream. |
|
154 */ |
|
155 double DestinationTimeFromTicks(AudioNodeStream* aDestination, |
|
156 TrackTicks aPosition); |
|
157 |
|
158 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; |
|
159 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE; |
|
160 |
|
161 void SizeOfAudioNodesIncludingThis(MallocSizeOf aMallocSizeOf, |
|
162 AudioNodeSizes& aUsage) const; |
|
163 |
|
164 protected: |
|
165 void AdvanceOutputSegment(); |
|
166 void FinishOutput(); |
|
167 void AccumulateInputChunk(uint32_t aInputIndex, const AudioChunk& aChunk, |
|
168 AudioChunk* aBlock, |
|
169 nsTArray<float>* aDownmixBuffer); |
|
170 void UpMixDownMixChunk(const AudioChunk* aChunk, uint32_t aOutputChannelCount, |
|
171 nsTArray<const void*>& aOutputChannels, |
|
172 nsTArray<float>& aDownmixBuffer); |
|
173 |
|
174 uint32_t ComputedNumberOfChannels(uint32_t aInputChannelCount); |
|
175 void ObtainInputBlock(AudioChunk& aTmpChunk, uint32_t aPortIndex); |
|
176 |
|
177 // The engine that will generate output for this node. |
|
178 nsAutoPtr<AudioNodeEngine> mEngine; |
|
179 // The last block produced by this node. |
|
180 OutputChunks mLastChunks; |
|
181 // The stream's sampling rate |
|
182 const TrackRate mSampleRate; |
|
183 // Whether this is an internal or external stream |
|
184 MediaStreamGraph::AudioNodeStreamKind mKind; |
|
185 // The number of input channels that this stream requires. 0 means don't care. |
|
186 uint32_t mNumberOfInputChannels; |
|
187 // The mixing modes |
|
188 ChannelCountMode mChannelCountMode; |
|
189 ChannelInterpretation mChannelInterpretation; |
|
190 // Whether the stream should be marked as finished as soon |
|
191 // as the current time range has been computed block by block. |
|
192 bool mMarkAsFinishedAfterThisBlock; |
|
193 // Whether the stream is an AudioParamHelper stream. |
|
194 bool mAudioParamStream; |
|
195 // Whether the stream is muted. Access only on the MediaStreamGraph thread. |
|
196 bool mMuted; |
|
197 }; |
|
198 |
|
199 } |
|
200 |
|
201 #endif /* MOZILLA_AUDIONODESTREAM_H_ */ |