Fri, 16 Jan 2015 04:50:19 +0100
Replace accessor implementation with direct member state manipulation, by
request https://trac.torproject.org/projects/tor/ticket/9701#comment:32
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)
17 {
18 CheckedInt<size_t> size = WEBAUDIO_BLOCK_SIZE;
19 size *= aChannelCount;
20 size *= sizeof(float);
21 if (!size.isValid()) {
22 MOZ_CRASH();
23 }
24 // XXX for SIMD purposes we should do something here to make sure the
25 // channel buffers are 16-byte aligned.
26 nsRefPtr<SharedBuffer> buffer = SharedBuffer::Create(size.value());
27 aChunk->mDuration = WEBAUDIO_BLOCK_SIZE;
28 aChunk->mChannelData.SetLength(aChannelCount);
29 float* data = static_cast<float*>(buffer->Data());
30 for (uint32_t i = 0; i < aChannelCount; ++i) {
31 aChunk->mChannelData[i] = data + i*WEBAUDIO_BLOCK_SIZE;
32 }
33 aChunk->mBuffer = buffer.forget();
34 aChunk->mVolume = 1.0f;
35 aChunk->mBufferFormat = AUDIO_FORMAT_FLOAT32;
36 }
38 void
39 WriteZeroesToAudioBlock(AudioChunk* aChunk, uint32_t aStart, uint32_t aLength)
40 {
41 MOZ_ASSERT(aStart + aLength <= WEBAUDIO_BLOCK_SIZE);
42 MOZ_ASSERT(!aChunk->IsNull(), "You should pass a non-null chunk");
43 if (aLength == 0)
44 return;
45 for (uint32_t i = 0; i < aChunk->mChannelData.Length(); ++i) {
46 memset(static_cast<float*>(const_cast<void*>(aChunk->mChannelData[i])) + aStart,
47 0, aLength*sizeof(float));
48 }
49 }
51 void AudioBufferCopyWithScale(const float* aInput,
52 float aScale,
53 float* aOutput,
54 uint32_t aSize)
55 {
56 if (aScale == 1.0f) {
57 PodCopy(aOutput, aInput, aSize);
58 } else {
59 for (uint32_t i = 0; i < aSize; ++i) {
60 aOutput[i] = aInput[i]*aScale;
61 }
62 }
63 }
65 void AudioBufferAddWithScale(const float* aInput,
66 float aScale,
67 float* aOutput,
68 uint32_t aSize)
69 {
70 #ifdef BUILD_ARM_NEON
71 if (mozilla::supports_neon()) {
72 AudioBufferAddWithScale_NEON(aInput, aScale, aOutput, aSize);
73 return;
74 }
75 #endif
76 if (aScale == 1.0f) {
77 for (uint32_t i = 0; i < aSize; ++i) {
78 aOutput[i] += aInput[i];
79 }
80 } else {
81 for (uint32_t i = 0; i < aSize; ++i) {
82 aOutput[i] += aInput[i]*aScale;
83 }
84 }
85 }
87 void
88 AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
89 float aScale,
90 float aOutput[WEBAUDIO_BLOCK_SIZE])
91 {
92 AudioBufferAddWithScale(aInput, aScale, aOutput, WEBAUDIO_BLOCK_SIZE);
93 }
95 void
96 AudioBlockCopyChannelWithScale(const float* aInput,
97 float aScale,
98 float* aOutput)
99 {
100 if (aScale == 1.0f) {
101 memcpy(aOutput, aInput, WEBAUDIO_BLOCK_SIZE*sizeof(float));
102 } else {
103 #ifdef BUILD_ARM_NEON
104 if (mozilla::supports_neon()) {
105 AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput);
106 return;
107 }
108 #endif
109 for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
110 aOutput[i] = aInput[i]*aScale;
111 }
112 }
113 }
115 void
116 BufferComplexMultiply(const float* aInput,
117 const float* aScale,
118 float* aOutput,
119 uint32_t aSize)
120 {
121 for (uint32_t i = 0; i < aSize * 2; i += 2) {
122 float real1 = aInput[i];
123 float imag1 = aInput[i + 1];
124 float real2 = aScale[i];
125 float imag2 = aScale[i + 1];
126 float realResult = real1 * real2 - imag1 * imag2;
127 float imagResult = real1 * imag2 + imag1 * real2;
128 aOutput[i] = realResult;
129 aOutput[i + 1] = imagResult;
130 }
131 }
133 float
134 AudioBufferPeakValue(const float *aInput, uint32_t aSize)
135 {
136 float max = 0.0f;
137 for (uint32_t i = 0; i < aSize; i++) {
138 float mag = fabs(aInput[i]);
139 if (mag > max) {
140 max = mag;
141 }
142 }
143 return max;
144 }
146 void
147 AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
148 const float aScale[WEBAUDIO_BLOCK_SIZE],
149 float aOutput[WEBAUDIO_BLOCK_SIZE])
150 {
151 #ifdef BUILD_ARM_NEON
152 if (mozilla::supports_neon()) {
153 AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput);
154 return;
155 }
156 #endif
157 for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
158 aOutput[i] = aInput[i]*aScale[i];
159 }
160 }
162 void
163 AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE],
164 float aScale)
165 {
166 AudioBufferInPlaceScale(aBlock, aScale, WEBAUDIO_BLOCK_SIZE);
167 }
169 void
170 AudioBufferInPlaceScale(float* aBlock,
171 float aScale,
172 uint32_t aSize)
173 {
174 if (aScale == 1.0f) {
175 return;
176 }
177 #ifdef BUILD_ARM_NEON
178 if (mozilla::supports_neon()) {
179 AudioBufferInPlaceScale_NEON(aBlock, aScale, aSize);
180 return;
181 }
182 #endif
183 for (uint32_t i = 0; i < aSize; ++i) {
184 *aBlock++ *= aScale;
185 }
186 }
188 void
189 AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
190 float aGainL, float aGainR,
191 float aOutputL[WEBAUDIO_BLOCK_SIZE],
192 float aOutputR[WEBAUDIO_BLOCK_SIZE])
193 {
194 AudioBlockCopyChannelWithScale(aInput, aGainL, aOutputL);
195 AudioBlockCopyChannelWithScale(aInput, aGainR, aOutputR);
196 }
198 void
199 AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
200 const float aInputR[WEBAUDIO_BLOCK_SIZE],
201 float aGainL, float aGainR, bool aIsOnTheLeft,
202 float aOutputL[WEBAUDIO_BLOCK_SIZE],
203 float aOutputR[WEBAUDIO_BLOCK_SIZE])
204 {
205 #ifdef BUILD_ARM_NEON
206 if (mozilla::supports_neon()) {
207 AudioBlockPanStereoToStereo_NEON(aInputL, aInputR,
208 aGainL, aGainR, aIsOnTheLeft,
209 aOutputL, aOutputR);
210 return;
211 }
212 #endif
214 uint32_t i;
216 if (aIsOnTheLeft) {
217 for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
218 *aOutputL++ = *aInputL++ + *aInputR * aGainL;
219 *aOutputR++ = *aInputR++ * aGainR;
220 }
221 } else {
222 for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
223 *aOutputL++ = *aInputL * aGainL;
224 *aOutputR++ = *aInputR++ + *aInputL++ * aGainR;
225 }
226 }
227 }
229 float
230 AudioBufferSumOfSquares(const float* aInput, uint32_t aLength)
231 {
232 float sum = 0.0f;
233 while (aLength--) {
234 sum += *aInput * *aInput;
235 ++aInput;
236 }
237 return sum;
238 }
240 }