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/. */
6 #ifndef MOZILLA_AUDIONODETRACK_H_
7 #define MOZILLA_AUDIONODETRACK_H_
9 #include "MediaTrackGraph.h"
10 #include "mozilla/dom/AudioNodeBinding.h"
11 #include "AlignedTArray.h"
12 #include "AudioBlock.h"
13 #include "AudioSegment.h"
17 } // namespace WebCore
23 struct AudioParamEvent
;
28 class ThreadSharedFloatArrayBufferList
;
29 class AudioNodeEngine
;
31 typedef AlignedAutoTArray
<float, GUESS_AUDIO_CHANNELS
* WEBAUDIO_BLOCK_SIZE
, 16>
35 * An AudioNodeTrack produces one audio track with ID AUDIO_TRACK.
36 * The start time of the AudioTrack is aligned to the start time of the
37 * AudioContext's destination node track, plus some multiple of BLOCK_SIZE
40 * An AudioNodeTrack has an AudioNodeEngine plugged into it that does the
41 * actual audio processing. AudioNodeTrack contains the glue code that
42 * integrates audio processing with the MediaTrackGraph.
44 class AudioNodeTrack
: public ProcessedMediaTrack
{
45 typedef dom::ChannelCountMode ChannelCountMode
;
46 typedef dom::ChannelInterpretation ChannelInterpretation
;
49 typedef mozilla::dom::AudioContext AudioContext
;
51 enum { AUDIO_TRACK
= 1 };
53 typedef AutoTArray
<AudioBlock
, 1> OutputChunks
;
55 // Flags re main thread updates and track output.
56 typedef unsigned Flags
;
59 NEED_MAIN_THREAD_ENDED
= 1U << 0,
60 NEED_MAIN_THREAD_CURRENT_TIME
= 1U << 1,
61 // Internal AudioNodeTracks can only pass their output to another
62 // AudioNode, whereas external AudioNodeTracks can pass their output
63 // to other ProcessedMediaTracks or hardware audio output.
64 EXTERNAL_OUTPUT
= 1U << 2,
67 * Create a track that will process audio for an AudioNode.
68 * Takes ownership of aEngine.
69 * aGraph is required and equals the graph of aCtx in most cases. An exception
70 * is AudioDestinationNode where the context's graph hasn't been set up yet.
72 static already_AddRefed
<AudioNodeTrack
> Create(AudioContext
* aCtx
,
73 AudioNodeEngine
* aEngine
,
75 MediaTrackGraph
* aGraph
);
79 * Transfers ownership of aEngine to the new AudioNodeTrack.
81 AudioNodeTrack(AudioNodeEngine
* aEngine
, Flags aFlags
, TrackRate aSampleRate
);
88 * Sets a parameter that's a time relative to some track's played time.
89 * This time is converted to a time relative to this track when it's set.
91 void SetTrackTimeParameter(uint32_t aIndex
, AudioContext
* aContext
,
93 void SetDoubleParameter(uint32_t aIndex
, double aValue
);
94 void SetInt32Parameter(uint32_t aIndex
, int32_t aValue
);
95 void SetThreeDPointParameter(uint32_t aIndex
, const dom::ThreeDPoint
& aValue
);
96 void SetBuffer(AudioChunk
&& aBuffer
);
97 void SetReverb(WebCore::Reverb
* aReverb
, uint32_t aImpulseChannelCount
);
98 // This sends a single event to the timeline on the MTG thread side.
99 void SendTimelineEvent(uint32_t aIndex
, const dom::AudioParamEvent
& aEvent
);
100 // This consumes the contents of aData. aData will be emptied after this
102 void SetRawArrayData(nsTArray
<float>&& aData
);
103 void SetChannelMixingParameters(uint32_t aNumberOfChannels
,
104 ChannelCountMode aChannelCountMoe
,
105 ChannelInterpretation aChannelInterpretation
);
106 void SetPassThrough(bool aPassThrough
);
107 void SendRunnable(already_AddRefed
<nsIRunnable
> aRunnable
);
108 ChannelInterpretation
GetChannelInterpretation() {
109 return mChannelInterpretation
;
112 void SetAudioParamHelperTrack() {
113 MOZ_ASSERT(!mAudioParamTrack
, "Can only do this once");
114 mAudioParamTrack
= true;
116 // The value for channelCount on an AudioNode, but on the audio thread side.
117 uint32_t NumberOfChannels() const override
;
120 * Resume track after updating its concept of current time by aAdvance.
121 * Main thread. Used only from AudioDestinationNode when resuming a track
122 * suspended to save running the MediaTrackGraph when there are no other
123 * nodes in the AudioContext.
125 void AdvanceAndResume(TrackTime aAdvance
);
127 AudioNodeTrack
* AsAudioNodeTrack() override
{ return this; }
128 void AddInput(MediaInputPort
* aPort
) override
;
129 void RemoveInput(MediaInputPort
* aPort
) override
;
132 void SetTrackTimeParameterImpl(uint32_t aIndex
, MediaTrack
* aRelativeToTrack
,
134 void SetChannelMixingParametersImpl(
135 uint32_t aNumberOfChannels
, ChannelCountMode aChannelCountMoe
,
136 ChannelInterpretation aChannelInterpretation
);
137 void ProcessInput(GraphTime aFrom
, GraphTime aTo
, uint32_t aFlags
) override
;
139 * Produce the next block of output, before input is provided.
140 * ProcessInput() will be called later, and it then should not change
141 * the output. This is used only for DelayNodeEngine in a feedback loop.
143 void ProduceOutputBeforeInput(GraphTime aFrom
);
144 bool IsAudioParamTrack() const { return mAudioParamTrack
; }
146 const OutputChunks
& LastChunks() const { return mLastChunks
; }
147 bool MainThreadNeedsUpdates() const override
{
148 return ((mFlags
& NEED_MAIN_THREAD_ENDED
) && mEnded
) ||
149 (mFlags
& NEED_MAIN_THREAD_CURRENT_TIME
);
153 AudioNodeEngine
* Engine() { return mEngine
.get(); }
155 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf
) const override
;
156 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf
) const override
;
158 void SizeOfAudioNodesIncludingThis(MallocSizeOf aMallocSizeOf
,
159 AudioNodeSizes
& aUsage
) const;
162 * SetActive() is called when either an active input is added or the engine
163 * for a source node transitions from inactive to active. This is not
164 * called from engines for processing nodes because they only become active
165 * when there are active input tracks, in which case this track is already
170 * ScheduleCheckForInactive() is called during track processing when the
171 * engine transitions from active to inactive, or the track finishes. It
172 * schedules a call to CheckForInactive() after track processing.
174 void ScheduleCheckForInactive();
177 void OnGraphThreadDone() override
;
178 void DestroyImpl() override
;
181 * CheckForInactive() is called when the engine transitions from active to
182 * inactive, or an active input is removed, or the track finishes. If the
183 * track is now inactive, then mInputChunks will be cleared and mLastChunks
184 * will be set to null. ProcessBlock() will not be called on the engine
185 * again until SetActive() is called.
187 void CheckForInactive();
189 void AdvanceOutputSegment();
191 void AccumulateInputChunk(uint32_t aInputIndex
, const AudioBlock
& aChunk
,
193 DownmixBufferType
* aDownmixBuffer
);
194 void UpMixDownMixChunk(const AudioBlock
* aChunk
, uint32_t aOutputChannelCount
,
195 nsTArray
<const float*>& aOutputChannels
,
196 DownmixBufferType
& aDownmixBuffer
);
198 uint32_t ComputedNumberOfChannels(uint32_t aInputChannelCount
);
199 void ObtainInputBlock(AudioBlock
& aTmpChunk
, uint32_t aPortIndex
);
200 void IncrementActiveInputCount();
201 void DecrementActiveInputCount();
203 // The engine that will generate output for this node.
204 const UniquePtr
<AudioNodeEngine
> mEngine
;
205 // The mixed input blocks are kept from iteration to iteration to avoid
206 // reallocating channel data arrays and any buffers for mixing.
207 OutputChunks mInputChunks
;
208 // The last block produced by this node.
209 OutputChunks mLastChunks
;
210 // Whether this is an internal or external track
212 // The number of input tracks that may provide non-silent input.
213 uint32_t mActiveInputCount
= 0;
214 // The number of input channels that this track requires. 0 means don't care.
215 uint32_t mNumberOfInputChannels
;
217 ChannelCountMode mChannelCountMode
;
218 ChannelInterpretation mChannelInterpretation
;
219 // Tracks are considered active if the track has not finished and either
220 // the engine is active or there are active input tracks.
222 // Whether the track should be marked as ended as soon
223 // as the current time range has been computed block by block.
224 bool mMarkAsEndedAfterThisBlock
;
225 // Whether the track is an AudioParamHelper track.
226 bool mAudioParamTrack
;
227 // Whether the track just passes its input through.
231 } // namespace mozilla
233 #endif /* MOZILLA_AUDIONODETRACK_H_ */