Bug 849918 - Initial support for PannerNode's 3D positional audio (equalpower panning...
[gecko.git] / content / media / AudioNodeEngine.h
blob8219f464f61f3524109eae038cc785d11c7f777c
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"
12 namespace mozilla {
14 namespace dom {
15 struct ThreeDPoint;
18 class AudioNodeStream;
20 // We ensure that the graph advances in steps that are multiples of the Web
21 // Audio block size
22 const uint32_t WEBAUDIO_BLOCK_SIZE_BITS = 7;
23 const uint32_t WEBAUDIO_BLOCK_SIZE = 1 << WEBAUDIO_BLOCK_SIZE_BITS;
25 /**
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 {
32 public:
33 /**
34 * Construct with null data.
36 ThreadSharedFloatArrayBufferList(uint32_t aCount)
38 mContents.SetLength(aCount);
41 struct Storage {
42 Storage()
44 mDataToFree = nullptr;
45 mSampleData = nullptr;
47 ~Storage() { free(mDataToFree); }
48 void* mDataToFree;
49 const float* mSampleData;
52 /**
53 * This can be called on any thread.
55 uint32_t GetChannels() const { return mContents.Length(); }
56 /**
57 * This can be called on any thread.
59 const float* GetData(uint32_t aIndex) const { return mContents[aIndex].mSampleData; }
61 /**
62 * Call this only during initialization, before the object is handed to
63 * any other thread.
65 void SetData(uint32_t aIndex, void* aDataToFree, const float* aData)
67 Storage* s = &mContents[aIndex];
68 free(s->mDataToFree);
69 s->mDataToFree = aDataToFree;
70 s->mSampleData = aData;
73 /**
74 * Put this object into an error state where there are no channels.
76 void Clear() { mContents.Clear(); }
78 private:
79 AutoFallibleTArray<Storage,2> mContents;
82 /**
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);
88 /**
89 * aChunk must have been allocated by AllocateAudioBlock.
91 void WriteZeroesToAudioBlock(AudioChunk* aChunk, uint32_t aStart, uint32_t aLength);
93 /**
94 * Pointwise multiply-add operation. aScale == 1.0f should be optimized.
96 void AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
97 float aScale,
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],
104 float aScale,
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,
119 float aScale);
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.
126 void
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.
136 void
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 {
148 public:
149 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,
191 AudioChunk* aOutput,
192 bool* aFinished)
194 *aOutput = aInput;
200 #endif /* MOZILLA_AUDIONODEENGINE_H_ */