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 #ifndef MOZILLA_AUDIONODEENGINE_H_
7 #define MOZILLA_AUDIONODEENGINE_H_
9 #include "AudioSegment.h"
10 #include "mozilla/dom/AudioParam.h"
18 class AudioNodeStream
;
20 // We ensure that the graph advances in steps that are multiples of the Web
22 const uint32_t WEBAUDIO_BLOCK_SIZE_BITS
= 7;
23 const uint32_t WEBAUDIO_BLOCK_SIZE
= 1 << WEBAUDIO_BLOCK_SIZE_BITS
;
26 * This class holds onto a set of immutable channel buffers. The storage
27 * for the buffers must be malloced, but the buffer pointers and the malloc
28 * pointers can be different (e.g. if the buffers are contained inside
29 * some malloced object).
31 class ThreadSharedFloatArrayBufferList
: public ThreadSharedObject
{
34 * Construct with null data.
36 ThreadSharedFloatArrayBufferList(uint32_t aCount
)
38 mContents
.SetLength(aCount
);
44 mDataToFree
= nullptr;
45 mSampleData
= nullptr;
47 ~Storage() { free(mDataToFree
); }
49 const float* mSampleData
;
53 * This can be called on any thread.
55 uint32_t GetChannels() const { return mContents
.Length(); }
57 * This can be called on any thread.
59 const float* GetData(uint32_t aIndex
) const { return mContents
[aIndex
].mSampleData
; }
62 * Call this only during initialization, before the object is handed to
65 void SetData(uint32_t aIndex
, void* aDataToFree
, const float* aData
)
67 Storage
* s
= &mContents
[aIndex
];
69 s
->mDataToFree
= aDataToFree
;
70 s
->mSampleData
= aData
;
74 * Put this object into an error state where there are no channels.
76 void Clear() { mContents
.Clear(); }
79 AutoFallibleTArray
<Storage
,2> mContents
;
83 * Allocates an AudioChunk with fresh buffers of WEBAUDIO_BLOCK_SIZE float samples.
84 * AudioChunk::mChannelData's entries can be cast to float* for writing.
86 void AllocateAudioBlock(uint32_t aChannelCount
, AudioChunk
* aChunk
);
89 * aChunk must have been allocated by AllocateAudioBlock.
91 void WriteZeroesToAudioBlock(AudioChunk
* aChunk
, uint32_t aStart
, uint32_t aLength
);
94 * Pointwise multiply-add operation. aScale == 1.0f should be optimized.
96 void AudioBlockAddChannelWithScale(const float aInput
[WEBAUDIO_BLOCK_SIZE
],
98 float aOutput
[WEBAUDIO_BLOCK_SIZE
]);
101 * Pointwise copy-scaled operation. aScale == 1.0f should be optimized.
103 void AudioBlockCopyChannelWithScale(const float aInput
[WEBAUDIO_BLOCK_SIZE
],
105 float aOutput
[WEBAUDIO_BLOCK_SIZE
]);
108 * Vector copy-scaled operation.
110 void AudioBlockCopyChannelWithScale(const float aInput
[WEBAUDIO_BLOCK_SIZE
],
111 const float aScale
[WEBAUDIO_BLOCK_SIZE
],
112 float aOutput
[WEBAUDIO_BLOCK_SIZE
]);
115 * In place gain. aScale == 1.0f should be optimized.
117 void AudioBlockInPlaceScale(float aBlock
[WEBAUDIO_BLOCK_SIZE
],
118 uint32_t aChannelCount
,
122 * Upmix a mono input to a stereo output, scaling the two output channels by two
123 * different gain value.
124 * This algorithm is specified in the WebAudio spec.
127 AudioBlockPanMonoToStereo(const float aInput
[WEBAUDIO_BLOCK_SIZE
],
128 float aGainL
, float aGainR
,
129 float aOutputL
[WEBAUDIO_BLOCK_SIZE
],
130 float aOutputR
[WEBAUDIO_BLOCK_SIZE
]);
132 * Pan a stereo source according to right and left gain, and the position
133 * (whether the listener is on the left of the source or not).
134 * This algorithm is specified in the WebAudio spec.
137 AudioBlockPanStereoToStereo(const float aInputL
[WEBAUDIO_BLOCK_SIZE
],
138 const float aInputR
[WEBAUDIO_BLOCK_SIZE
],
139 float aGainL
, float aGainR
, bool aIsOnTheLeft
,
140 float aOutputL
[WEBAUDIO_BLOCK_SIZE
],
141 float aOutputR
[WEBAUDIO_BLOCK_SIZE
]);
144 * All methods of this class and its subclasses are called on the
145 * MediaStreamGraph thread.
147 class AudioNodeEngine
{
150 virtual ~AudioNodeEngine() {}
152 virtual void SetStreamTimeParameter(uint32_t aIndex
, TrackTicks aParam
)
154 NS_ERROR("Invalid SetStreamTimeParameter index");
156 virtual void SetDoubleParameter(uint32_t aIndex
, double aParam
)
158 NS_ERROR("Invalid SetDoubleParameter index");
160 virtual void SetInt32Parameter(uint32_t aIndex
, int32_t aParam
)
162 NS_ERROR("Invalid SetInt32Parameter index");
164 virtual void SetTimelineParameter(uint32_t aIndex
,
165 const dom::AudioParamTimeline
& aValue
)
167 NS_ERROR("Invalid SetTimelineParameter index");
169 virtual void SetThreeDPointParameter(uint32_t aIndex
,
170 const dom::ThreeDPoint
& aValue
)
172 NS_ERROR("Invalid SetThreeDPointParameter index");
174 virtual void SetBuffer(already_AddRefed
<ThreadSharedFloatArrayBufferList
> aBuffer
)
176 NS_ERROR("SetBuffer called on engine that doesn't support it");
180 * Produce the next block of audio samples, given input samples aInput
181 * (the mixed data for input 0).
182 * By default, simply returns the mixed input.
183 * aInput is guaranteed to have float sample format (if it has samples at all)
184 * and to have been resampled to IdealAudioRate(), and to have exactly
185 * WEBAUDIO_BLOCK_SIZE samples.
186 * *aFinished is set to false by the caller. If the callee sets it to true,
187 * we'll finish the stream and not call this again.
189 virtual void ProduceAudioBlock(AudioNodeStream
* aStream
,
190 const AudioChunk
& aInput
,
200 #endif /* MOZILLA_AUDIONODEENGINE_H_ */