1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/AudioNodeEngine.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,240 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set ts=2 sw=2 sts=2 et cindent: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "AudioNodeEngine.h" 1.11 +#ifdef BUILD_ARM_NEON 1.12 +#include "mozilla/arm.h" 1.13 +#include "AudioNodeEngineNEON.h" 1.14 +#endif 1.15 + 1.16 +namespace mozilla { 1.17 + 1.18 +void 1.19 +AllocateAudioBlock(uint32_t aChannelCount, AudioChunk* aChunk) 1.20 +{ 1.21 + CheckedInt<size_t> size = WEBAUDIO_BLOCK_SIZE; 1.22 + size *= aChannelCount; 1.23 + size *= sizeof(float); 1.24 + if (!size.isValid()) { 1.25 + MOZ_CRASH(); 1.26 + } 1.27 + // XXX for SIMD purposes we should do something here to make sure the 1.28 + // channel buffers are 16-byte aligned. 1.29 + nsRefPtr<SharedBuffer> buffer = SharedBuffer::Create(size.value()); 1.30 + aChunk->mDuration = WEBAUDIO_BLOCK_SIZE; 1.31 + aChunk->mChannelData.SetLength(aChannelCount); 1.32 + float* data = static_cast<float*>(buffer->Data()); 1.33 + for (uint32_t i = 0; i < aChannelCount; ++i) { 1.34 + aChunk->mChannelData[i] = data + i*WEBAUDIO_BLOCK_SIZE; 1.35 + } 1.36 + aChunk->mBuffer = buffer.forget(); 1.37 + aChunk->mVolume = 1.0f; 1.38 + aChunk->mBufferFormat = AUDIO_FORMAT_FLOAT32; 1.39 +} 1.40 + 1.41 +void 1.42 +WriteZeroesToAudioBlock(AudioChunk* aChunk, uint32_t aStart, uint32_t aLength) 1.43 +{ 1.44 + MOZ_ASSERT(aStart + aLength <= WEBAUDIO_BLOCK_SIZE); 1.45 + MOZ_ASSERT(!aChunk->IsNull(), "You should pass a non-null chunk"); 1.46 + if (aLength == 0) 1.47 + return; 1.48 + for (uint32_t i = 0; i < aChunk->mChannelData.Length(); ++i) { 1.49 + memset(static_cast<float*>(const_cast<void*>(aChunk->mChannelData[i])) + aStart, 1.50 + 0, aLength*sizeof(float)); 1.51 + } 1.52 +} 1.53 + 1.54 +void AudioBufferCopyWithScale(const float* aInput, 1.55 + float aScale, 1.56 + float* aOutput, 1.57 + uint32_t aSize) 1.58 +{ 1.59 + if (aScale == 1.0f) { 1.60 + PodCopy(aOutput, aInput, aSize); 1.61 + } else { 1.62 + for (uint32_t i = 0; i < aSize; ++i) { 1.63 + aOutput[i] = aInput[i]*aScale; 1.64 + } 1.65 + } 1.66 +} 1.67 + 1.68 +void AudioBufferAddWithScale(const float* aInput, 1.69 + float aScale, 1.70 + float* aOutput, 1.71 + uint32_t aSize) 1.72 +{ 1.73 +#ifdef BUILD_ARM_NEON 1.74 + if (mozilla::supports_neon()) { 1.75 + AudioBufferAddWithScale_NEON(aInput, aScale, aOutput, aSize); 1.76 + return; 1.77 + } 1.78 +#endif 1.79 + if (aScale == 1.0f) { 1.80 + for (uint32_t i = 0; i < aSize; ++i) { 1.81 + aOutput[i] += aInput[i]; 1.82 + } 1.83 + } else { 1.84 + for (uint32_t i = 0; i < aSize; ++i) { 1.85 + aOutput[i] += aInput[i]*aScale; 1.86 + } 1.87 + } 1.88 +} 1.89 + 1.90 +void 1.91 +AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE], 1.92 + float aScale, 1.93 + float aOutput[WEBAUDIO_BLOCK_SIZE]) 1.94 +{ 1.95 + AudioBufferAddWithScale(aInput, aScale, aOutput, WEBAUDIO_BLOCK_SIZE); 1.96 +} 1.97 + 1.98 +void 1.99 +AudioBlockCopyChannelWithScale(const float* aInput, 1.100 + float aScale, 1.101 + float* aOutput) 1.102 +{ 1.103 + if (aScale == 1.0f) { 1.104 + memcpy(aOutput, aInput, WEBAUDIO_BLOCK_SIZE*sizeof(float)); 1.105 + } else { 1.106 +#ifdef BUILD_ARM_NEON 1.107 + if (mozilla::supports_neon()) { 1.108 + AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput); 1.109 + return; 1.110 + } 1.111 +#endif 1.112 + for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) { 1.113 + aOutput[i] = aInput[i]*aScale; 1.114 + } 1.115 + } 1.116 +} 1.117 + 1.118 +void 1.119 +BufferComplexMultiply(const float* aInput, 1.120 + const float* aScale, 1.121 + float* aOutput, 1.122 + uint32_t aSize) 1.123 +{ 1.124 + for (uint32_t i = 0; i < aSize * 2; i += 2) { 1.125 + float real1 = aInput[i]; 1.126 + float imag1 = aInput[i + 1]; 1.127 + float real2 = aScale[i]; 1.128 + float imag2 = aScale[i + 1]; 1.129 + float realResult = real1 * real2 - imag1 * imag2; 1.130 + float imagResult = real1 * imag2 + imag1 * real2; 1.131 + aOutput[i] = realResult; 1.132 + aOutput[i + 1] = imagResult; 1.133 + } 1.134 +} 1.135 + 1.136 +float 1.137 +AudioBufferPeakValue(const float *aInput, uint32_t aSize) 1.138 +{ 1.139 + float max = 0.0f; 1.140 + for (uint32_t i = 0; i < aSize; i++) { 1.141 + float mag = fabs(aInput[i]); 1.142 + if (mag > max) { 1.143 + max = mag; 1.144 + } 1.145 + } 1.146 + return max; 1.147 +} 1.148 + 1.149 +void 1.150 +AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE], 1.151 + const float aScale[WEBAUDIO_BLOCK_SIZE], 1.152 + float aOutput[WEBAUDIO_BLOCK_SIZE]) 1.153 +{ 1.154 +#ifdef BUILD_ARM_NEON 1.155 + if (mozilla::supports_neon()) { 1.156 + AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput); 1.157 + return; 1.158 + } 1.159 +#endif 1.160 + for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) { 1.161 + aOutput[i] = aInput[i]*aScale[i]; 1.162 + } 1.163 +} 1.164 + 1.165 +void 1.166 +AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE], 1.167 + float aScale) 1.168 +{ 1.169 + AudioBufferInPlaceScale(aBlock, aScale, WEBAUDIO_BLOCK_SIZE); 1.170 +} 1.171 + 1.172 +void 1.173 +AudioBufferInPlaceScale(float* aBlock, 1.174 + float aScale, 1.175 + uint32_t aSize) 1.176 +{ 1.177 + if (aScale == 1.0f) { 1.178 + return; 1.179 + } 1.180 +#ifdef BUILD_ARM_NEON 1.181 + if (mozilla::supports_neon()) { 1.182 + AudioBufferInPlaceScale_NEON(aBlock, aScale, aSize); 1.183 + return; 1.184 + } 1.185 +#endif 1.186 + for (uint32_t i = 0; i < aSize; ++i) { 1.187 + *aBlock++ *= aScale; 1.188 + } 1.189 +} 1.190 + 1.191 +void 1.192 +AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE], 1.193 + float aGainL, float aGainR, 1.194 + float aOutputL[WEBAUDIO_BLOCK_SIZE], 1.195 + float aOutputR[WEBAUDIO_BLOCK_SIZE]) 1.196 +{ 1.197 + AudioBlockCopyChannelWithScale(aInput, aGainL, aOutputL); 1.198 + AudioBlockCopyChannelWithScale(aInput, aGainR, aOutputR); 1.199 +} 1.200 + 1.201 +void 1.202 +AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE], 1.203 + const float aInputR[WEBAUDIO_BLOCK_SIZE], 1.204 + float aGainL, float aGainR, bool aIsOnTheLeft, 1.205 + float aOutputL[WEBAUDIO_BLOCK_SIZE], 1.206 + float aOutputR[WEBAUDIO_BLOCK_SIZE]) 1.207 +{ 1.208 +#ifdef BUILD_ARM_NEON 1.209 + if (mozilla::supports_neon()) { 1.210 + AudioBlockPanStereoToStereo_NEON(aInputL, aInputR, 1.211 + aGainL, aGainR, aIsOnTheLeft, 1.212 + aOutputL, aOutputR); 1.213 + return; 1.214 + } 1.215 +#endif 1.216 + 1.217 + uint32_t i; 1.218 + 1.219 + if (aIsOnTheLeft) { 1.220 + for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) { 1.221 + *aOutputL++ = *aInputL++ + *aInputR * aGainL; 1.222 + *aOutputR++ = *aInputR++ * aGainR; 1.223 + } 1.224 + } else { 1.225 + for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) { 1.226 + *aOutputL++ = *aInputL * aGainL; 1.227 + *aOutputR++ = *aInputR++ + *aInputL++ * aGainR; 1.228 + } 1.229 + } 1.230 +} 1.231 + 1.232 +float 1.233 +AudioBufferSumOfSquares(const float* aInput, uint32_t aLength) 1.234 +{ 1.235 + float sum = 0.0f; 1.236 + while (aLength--) { 1.237 + sum += *aInput * *aInput; 1.238 + ++aInput; 1.239 + } 1.240 + return sum; 1.241 +} 1.242 + 1.243 +}