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"
9 #include "mozilla/arm.h"
10 #include "AudioNodeEngineNEON.h"
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
;
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");
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
,
52 PodCopy(aOutput
, aInput
, aSize
);
54 for (uint32_t i
= 0; i
< aSize
; ++i
) {
55 aOutput
[i
] = aInput
[i
]*aScale
;
60 void AudioBufferAddWithScale(const float* aInput
,
66 if (mozilla::supports_neon()) {
67 AudioBufferAddWithScale_NEON(aInput
, aScale
, aOutput
, aSize
);
72 for (uint32_t i
= 0; i
< aSize
; ++i
) {
73 aOutput
[i
] += aInput
[i
];
76 for (uint32_t i
= 0; i
< aSize
; ++i
) {
77 aOutput
[i
] += aInput
[i
]*aScale
;
83 AudioBlockAddChannelWithScale(const float aInput
[WEBAUDIO_BLOCK_SIZE
],
85 float aOutput
[WEBAUDIO_BLOCK_SIZE
])
87 AudioBufferAddWithScale(aInput
, aScale
, aOutput
, WEBAUDIO_BLOCK_SIZE
);
91 AudioBlockCopyChannelWithScale(const float* aInput
,
96 memcpy(aOutput
, aInput
, WEBAUDIO_BLOCK_SIZE
*sizeof(float));
99 if (mozilla::supports_neon()) {
100 AudioBlockCopyChannelWithScale_NEON(aInput
, aScale
, aOutput
);
104 for (uint32_t i
= 0; i
< WEBAUDIO_BLOCK_SIZE
; ++i
) {
105 aOutput
[i
] = aInput
[i
]*aScale
;
111 BufferComplexMultiply(const float* aInput
,
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
;
129 AudioBufferPeakValue(const float *aInput
, uint32_t aSize
)
132 for (uint32_t i
= 0; i
< aSize
; i
++) {
133 float mag
= fabs(aInput
[i
]);
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
);
152 for (uint32_t i
= 0; i
< WEBAUDIO_BLOCK_SIZE
; ++i
) {
153 aOutput
[i
] = aInput
[i
]*aScale
[i
];
158 AudioBlockInPlaceScale(float aBlock
[WEBAUDIO_BLOCK_SIZE
],
159 uint32_t aChannelCount
,
162 AudioBufferInPlaceScale(aBlock
, aScale
, aChannelCount
* WEBAUDIO_BLOCK_SIZE
);
166 AudioBufferInPlaceScale(float* aBlock
,
170 if (aScale
== 1.0f
) {
173 #ifdef BUILD_ARM_NEON
174 if (mozilla::supports_neon()) {
175 AudioBufferInPlaceScale_NEON(aBlock
, aScale
, aSize
);
179 for (uint32_t i
= 0; i
< aSize
; ++i
) {
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
);
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
,
213 for (i
= 0; i
< WEBAUDIO_BLOCK_SIZE
; ++i
) {
214 *aOutputL
++ = *aInputL
++ + *aInputR
* aGainL
;
215 *aOutputR
++ = *aInputR
++ * aGainR
;
218 for (i
= 0; i
< WEBAUDIO_BLOCK_SIZE
; ++i
) {
219 *aOutputL
++ = *aInputL
* aGainL
;
220 *aOutputR
++ = *aInputR
++ + *aInputL
++ * aGainR
;
226 AudioBufferSumOfSquares(const float* aInput
, uint32_t aLength
)
230 sum
+= *aInput
* *aInput
;