content/media/AudioNodeEngine.cpp

changeset 0
6474c204b198
     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 +}

mercurial