content/media/AudioNodeEngine.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "AudioNodeEngine.h"
michael@0 8 #ifdef BUILD_ARM_NEON
michael@0 9 #include "mozilla/arm.h"
michael@0 10 #include "AudioNodeEngineNEON.h"
michael@0 11 #endif
michael@0 12
michael@0 13 namespace mozilla {
michael@0 14
michael@0 15 void
michael@0 16 AllocateAudioBlock(uint32_t aChannelCount, AudioChunk* aChunk)
michael@0 17 {
michael@0 18 CheckedInt<size_t> size = WEBAUDIO_BLOCK_SIZE;
michael@0 19 size *= aChannelCount;
michael@0 20 size *= sizeof(float);
michael@0 21 if (!size.isValid()) {
michael@0 22 MOZ_CRASH();
michael@0 23 }
michael@0 24 // XXX for SIMD purposes we should do something here to make sure the
michael@0 25 // channel buffers are 16-byte aligned.
michael@0 26 nsRefPtr<SharedBuffer> buffer = SharedBuffer::Create(size.value());
michael@0 27 aChunk->mDuration = WEBAUDIO_BLOCK_SIZE;
michael@0 28 aChunk->mChannelData.SetLength(aChannelCount);
michael@0 29 float* data = static_cast<float*>(buffer->Data());
michael@0 30 for (uint32_t i = 0; i < aChannelCount; ++i) {
michael@0 31 aChunk->mChannelData[i] = data + i*WEBAUDIO_BLOCK_SIZE;
michael@0 32 }
michael@0 33 aChunk->mBuffer = buffer.forget();
michael@0 34 aChunk->mVolume = 1.0f;
michael@0 35 aChunk->mBufferFormat = AUDIO_FORMAT_FLOAT32;
michael@0 36 }
michael@0 37
michael@0 38 void
michael@0 39 WriteZeroesToAudioBlock(AudioChunk* aChunk, uint32_t aStart, uint32_t aLength)
michael@0 40 {
michael@0 41 MOZ_ASSERT(aStart + aLength <= WEBAUDIO_BLOCK_SIZE);
michael@0 42 MOZ_ASSERT(!aChunk->IsNull(), "You should pass a non-null chunk");
michael@0 43 if (aLength == 0)
michael@0 44 return;
michael@0 45 for (uint32_t i = 0; i < aChunk->mChannelData.Length(); ++i) {
michael@0 46 memset(static_cast<float*>(const_cast<void*>(aChunk->mChannelData[i])) + aStart,
michael@0 47 0, aLength*sizeof(float));
michael@0 48 }
michael@0 49 }
michael@0 50
michael@0 51 void AudioBufferCopyWithScale(const float* aInput,
michael@0 52 float aScale,
michael@0 53 float* aOutput,
michael@0 54 uint32_t aSize)
michael@0 55 {
michael@0 56 if (aScale == 1.0f) {
michael@0 57 PodCopy(aOutput, aInput, aSize);
michael@0 58 } else {
michael@0 59 for (uint32_t i = 0; i < aSize; ++i) {
michael@0 60 aOutput[i] = aInput[i]*aScale;
michael@0 61 }
michael@0 62 }
michael@0 63 }
michael@0 64
michael@0 65 void AudioBufferAddWithScale(const float* aInput,
michael@0 66 float aScale,
michael@0 67 float* aOutput,
michael@0 68 uint32_t aSize)
michael@0 69 {
michael@0 70 #ifdef BUILD_ARM_NEON
michael@0 71 if (mozilla::supports_neon()) {
michael@0 72 AudioBufferAddWithScale_NEON(aInput, aScale, aOutput, aSize);
michael@0 73 return;
michael@0 74 }
michael@0 75 #endif
michael@0 76 if (aScale == 1.0f) {
michael@0 77 for (uint32_t i = 0; i < aSize; ++i) {
michael@0 78 aOutput[i] += aInput[i];
michael@0 79 }
michael@0 80 } else {
michael@0 81 for (uint32_t i = 0; i < aSize; ++i) {
michael@0 82 aOutput[i] += aInput[i]*aScale;
michael@0 83 }
michael@0 84 }
michael@0 85 }
michael@0 86
michael@0 87 void
michael@0 88 AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
michael@0 89 float aScale,
michael@0 90 float aOutput[WEBAUDIO_BLOCK_SIZE])
michael@0 91 {
michael@0 92 AudioBufferAddWithScale(aInput, aScale, aOutput, WEBAUDIO_BLOCK_SIZE);
michael@0 93 }
michael@0 94
michael@0 95 void
michael@0 96 AudioBlockCopyChannelWithScale(const float* aInput,
michael@0 97 float aScale,
michael@0 98 float* aOutput)
michael@0 99 {
michael@0 100 if (aScale == 1.0f) {
michael@0 101 memcpy(aOutput, aInput, WEBAUDIO_BLOCK_SIZE*sizeof(float));
michael@0 102 } else {
michael@0 103 #ifdef BUILD_ARM_NEON
michael@0 104 if (mozilla::supports_neon()) {
michael@0 105 AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput);
michael@0 106 return;
michael@0 107 }
michael@0 108 #endif
michael@0 109 for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
michael@0 110 aOutput[i] = aInput[i]*aScale;
michael@0 111 }
michael@0 112 }
michael@0 113 }
michael@0 114
michael@0 115 void
michael@0 116 BufferComplexMultiply(const float* aInput,
michael@0 117 const float* aScale,
michael@0 118 float* aOutput,
michael@0 119 uint32_t aSize)
michael@0 120 {
michael@0 121 for (uint32_t i = 0; i < aSize * 2; i += 2) {
michael@0 122 float real1 = aInput[i];
michael@0 123 float imag1 = aInput[i + 1];
michael@0 124 float real2 = aScale[i];
michael@0 125 float imag2 = aScale[i + 1];
michael@0 126 float realResult = real1 * real2 - imag1 * imag2;
michael@0 127 float imagResult = real1 * imag2 + imag1 * real2;
michael@0 128 aOutput[i] = realResult;
michael@0 129 aOutput[i + 1] = imagResult;
michael@0 130 }
michael@0 131 }
michael@0 132
michael@0 133 float
michael@0 134 AudioBufferPeakValue(const float *aInput, uint32_t aSize)
michael@0 135 {
michael@0 136 float max = 0.0f;
michael@0 137 for (uint32_t i = 0; i < aSize; i++) {
michael@0 138 float mag = fabs(aInput[i]);
michael@0 139 if (mag > max) {
michael@0 140 max = mag;
michael@0 141 }
michael@0 142 }
michael@0 143 return max;
michael@0 144 }
michael@0 145
michael@0 146 void
michael@0 147 AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
michael@0 148 const float aScale[WEBAUDIO_BLOCK_SIZE],
michael@0 149 float aOutput[WEBAUDIO_BLOCK_SIZE])
michael@0 150 {
michael@0 151 #ifdef BUILD_ARM_NEON
michael@0 152 if (mozilla::supports_neon()) {
michael@0 153 AudioBlockCopyChannelWithScale_NEON(aInput, aScale, aOutput);
michael@0 154 return;
michael@0 155 }
michael@0 156 #endif
michael@0 157 for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
michael@0 158 aOutput[i] = aInput[i]*aScale[i];
michael@0 159 }
michael@0 160 }
michael@0 161
michael@0 162 void
michael@0 163 AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE],
michael@0 164 float aScale)
michael@0 165 {
michael@0 166 AudioBufferInPlaceScale(aBlock, aScale, WEBAUDIO_BLOCK_SIZE);
michael@0 167 }
michael@0 168
michael@0 169 void
michael@0 170 AudioBufferInPlaceScale(float* aBlock,
michael@0 171 float aScale,
michael@0 172 uint32_t aSize)
michael@0 173 {
michael@0 174 if (aScale == 1.0f) {
michael@0 175 return;
michael@0 176 }
michael@0 177 #ifdef BUILD_ARM_NEON
michael@0 178 if (mozilla::supports_neon()) {
michael@0 179 AudioBufferInPlaceScale_NEON(aBlock, aScale, aSize);
michael@0 180 return;
michael@0 181 }
michael@0 182 #endif
michael@0 183 for (uint32_t i = 0; i < aSize; ++i) {
michael@0 184 *aBlock++ *= aScale;
michael@0 185 }
michael@0 186 }
michael@0 187
michael@0 188 void
michael@0 189 AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
michael@0 190 float aGainL, float aGainR,
michael@0 191 float aOutputL[WEBAUDIO_BLOCK_SIZE],
michael@0 192 float aOutputR[WEBAUDIO_BLOCK_SIZE])
michael@0 193 {
michael@0 194 AudioBlockCopyChannelWithScale(aInput, aGainL, aOutputL);
michael@0 195 AudioBlockCopyChannelWithScale(aInput, aGainR, aOutputR);
michael@0 196 }
michael@0 197
michael@0 198 void
michael@0 199 AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
michael@0 200 const float aInputR[WEBAUDIO_BLOCK_SIZE],
michael@0 201 float aGainL, float aGainR, bool aIsOnTheLeft,
michael@0 202 float aOutputL[WEBAUDIO_BLOCK_SIZE],
michael@0 203 float aOutputR[WEBAUDIO_BLOCK_SIZE])
michael@0 204 {
michael@0 205 #ifdef BUILD_ARM_NEON
michael@0 206 if (mozilla::supports_neon()) {
michael@0 207 AudioBlockPanStereoToStereo_NEON(aInputL, aInputR,
michael@0 208 aGainL, aGainR, aIsOnTheLeft,
michael@0 209 aOutputL, aOutputR);
michael@0 210 return;
michael@0 211 }
michael@0 212 #endif
michael@0 213
michael@0 214 uint32_t i;
michael@0 215
michael@0 216 if (aIsOnTheLeft) {
michael@0 217 for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
michael@0 218 *aOutputL++ = *aInputL++ + *aInputR * aGainL;
michael@0 219 *aOutputR++ = *aInputR++ * aGainR;
michael@0 220 }
michael@0 221 } else {
michael@0 222 for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
michael@0 223 *aOutputL++ = *aInputL * aGainL;
michael@0 224 *aOutputR++ = *aInputR++ + *aInputL++ * aGainR;
michael@0 225 }
michael@0 226 }
michael@0 227 }
michael@0 228
michael@0 229 float
michael@0 230 AudioBufferSumOfSquares(const float* aInput, uint32_t aLength)
michael@0 231 {
michael@0 232 float sum = 0.0f;
michael@0 233 while (aLength--) {
michael@0 234 sum += *aInput * *aInput;
michael@0 235 ++aInput;
michael@0 236 }
michael@0 237 return sum;
michael@0 238 }
michael@0 239
michael@0 240 }

mercurial