Backout a74bd5095902, Bug 959405 - Please update the Buri Moz-central, 1.3, 1.2 with...
[gecko.git] / content / media / AudioNodeEngine.cpp
blob3aec7aef6c8586c368b87a6290cc763e9f64c976
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/. */
7 #include "AudioNodeEngine.h"
8 #ifdef BUILD_ARM_NEON
9 #include "mozilla/arm.h"
10 #include "AudioNodeEngineNEON.h"
11 #endif
13 namespace mozilla {
15 void
16 AllocateAudioBlock(uint32_t aChannelCount, AudioChunk* aChunk)
18 // XXX for SIMD purposes we should do something here to make sure the
19 // channel buffers are 16-byte aligned.
20 nsRefPtr<SharedBuffer> buffer =
21 SharedBuffer::Create(WEBAUDIO_BLOCK_SIZE*aChannelCount*sizeof(float));
22 aChunk->mDuration = WEBAUDIO_BLOCK_SIZE;
23 aChunk->mChannelData.SetLength(aChannelCount);
24 float* data = static_cast<float*>(buffer->Data());
25 for (uint32_t i = 0; i < aChannelCount; ++i) {
26 aChunk->mChannelData[i] = data + i*WEBAUDIO_BLOCK_SIZE;
28 aChunk->mBuffer = buffer.forget();
29 aChunk->mVolume = 1.0f;
30 aChunk->mBufferFormat = AUDIO_FORMAT_FLOAT32;
33 void
34 WriteZeroesToAudioBlock(AudioChunk* aChunk, uint32_t aStart, uint32_t aLength)
36 MOZ_ASSERT(aStart + aLength <= WEBAUDIO_BLOCK_SIZE);
37 MOZ_ASSERT(!aChunk->IsNull(), "You should pass a non-null chunk");
38 if (aLength == 0)
39 return;
40 for (uint32_t i = 0; i < aChunk->mChannelData.Length(); ++i) {
41 memset(static_cast<float*>(const_cast<void*>(aChunk->mChannelData[i])) + aStart,
42 0, aLength*sizeof(float));
46 void AudioBufferCopyWithScale(const float* aInput,
47 float aScale,
48 float* aOutput,
49 uint32_t aSize)
51 if (aScale == 1.0f) {
52 PodCopy(aOutput, aInput, aSize);
53 } else {
54 for (uint32_t i = 0; i < aSize; ++i) {
55 aOutput[i] = aInput[i]*aScale;
60 void AudioBufferAddWithScale(const float* aInput,
61 float aScale,
62 float* aOutput,
63 uint32_t aSize)
65 #ifdef BUILD_ARM_NEON
66 if (mozilla::supports_neon()) {
67 AudioBufferAddWithScale_NEON(aInput, aScale, aOutput, aSize);
68 return;
70 #endif
71 if (aScale == 1.0f) {
72 for (uint32_t i = 0; i < aSize; ++i) {
73 aOutput[i] += aInput[i];
75 } else {
76 for (uint32_t i = 0; i < aSize; ++i) {
77 aOutput[i] += aInput[i]*aScale;
82 void
83 AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
84 float aScale,
85 float aOutput[WEBAUDIO_BLOCK_SIZE])
87 AudioBufferAddWithScale(aInput, aScale, aOutput, WEBAUDIO_BLOCK_SIZE);
90 void
91 AudioBlockCopyChannelWithScale(const float* aInput,
92 float aScale,
93 float* aOutput)
95 if (aScale == 1.0f) {
96 memcpy(aOutput, aInput, WEBAUDIO_BLOCK_SIZE*sizeof(float));
97 } else {
98 #ifdef BUILD_ARM_NEON
99 if (mozilla::supports_neon()) {
100 AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput);
101 return;
103 #endif
104 for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
105 aOutput[i] = aInput[i]*aScale;
110 void
111 BufferComplexMultiply(const float* aInput,
112 const float* aScale,
113 float* aOutput,
114 uint32_t aSize)
116 for (uint32_t i = 0; i < aSize * 2; i += 2) {
117 float real1 = aInput[i];
118 float imag1 = aInput[i + 1];
119 float real2 = aScale[i];
120 float imag2 = aScale[i + 1];
121 float realResult = real1 * real2 - imag1 * imag2;
122 float imagResult = real1 * imag2 + imag1 * real2;
123 aOutput[i] = realResult;
124 aOutput[i + 1] = imagResult;
128 float
129 AudioBufferPeakValue(const float *aInput, uint32_t aSize)
131 float max = 0.0f;
132 for (uint32_t i = 0; i < aSize; i++) {
133 float mag = fabs(aInput[i]);
134 if (mag > max) {
135 max = mag;
138 return max;
141 void
142 AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
143 const float aScale[WEBAUDIO_BLOCK_SIZE],
144 float aOutput[WEBAUDIO_BLOCK_SIZE])
146 #ifdef BUILD_ARM_NEON
147 if (mozilla::supports_neon()) {
148 AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput);
149 return;
151 #endif
152 for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
153 aOutput[i] = aInput[i]*aScale[i];
157 void
158 AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE],
159 uint32_t aChannelCount,
160 float aScale)
162 AudioBufferInPlaceScale(aBlock, aScale, aChannelCount * WEBAUDIO_BLOCK_SIZE);
165 void
166 AudioBufferInPlaceScale(float* aBlock,
167 float aScale,
168 uint32_t aSize)
170 if (aScale == 1.0f) {
171 return;
173 #ifdef BUILD_ARM_NEON
174 if (mozilla::supports_neon()) {
175 AudioBufferInPlaceScale_NEON(aBlock, aScale, aSize);
176 return;
178 #endif
179 for (uint32_t i = 0; i < aSize; ++i) {
180 *aBlock++ *= aScale;
184 void
185 AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
186 float aGainL, float aGainR,
187 float aOutputL[WEBAUDIO_BLOCK_SIZE],
188 float aOutputR[WEBAUDIO_BLOCK_SIZE])
190 AudioBlockCopyChannelWithScale(aInput, aGainL, aOutputL);
191 AudioBlockCopyChannelWithScale(aInput, aGainR, aOutputR);
194 void
195 AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
196 const float aInputR[WEBAUDIO_BLOCK_SIZE],
197 float aGainL, float aGainR, bool aIsOnTheLeft,
198 float aOutputL[WEBAUDIO_BLOCK_SIZE],
199 float aOutputR[WEBAUDIO_BLOCK_SIZE])
201 #ifdef BUILD_ARM_NEON
202 if (mozilla::supports_neon()) {
203 AudioBlockPanStereoToStereo_NEON(aInputL, aInputR,
204 aGainL, aGainR, aIsOnTheLeft,
205 aOutputL, aOutputR);
206 return;
208 #endif
210 uint32_t i;
212 if (aIsOnTheLeft) {
213 for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
214 *aOutputL++ = *aInputL++ + *aInputR * aGainL;
215 *aOutputR++ = *aInputR++ * aGainR;
217 } else {
218 for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
219 *aOutputL++ = *aInputL * aGainL;
220 *aOutputR++ = *aInputR++ + *aInputL++ * aGainR;
225 float
226 AudioBufferSumOfSquares(const float* aInput, uint32_t aLength)
228 float sum = 0.0f;
229 while (aLength--) {
230 sum += *aInput * *aInput;
231 ++aInput;
233 return sum;