tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PeriodicWave.cpp (4307B)


      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/. */
      6 
      7 #include "PeriodicWave.h"
      8 
      9 #include "AudioContext.h"
     10 #include "mozilla/dom/PeriodicWaveBinding.h"
     11 
     12 namespace mozilla::dom {
     13 
     14 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(PeriodicWave, mContext)
     15 
     16 PeriodicWave::PeriodicWave(AudioContext* aContext, const float* aRealData,
     17                           const uint32_t aRealSize, const float* aImagData,
     18                           const uint32_t aImagSize,
     19                           const bool aDisableNormalization, ErrorResult& aRv)
     20    : mContext(aContext), mDisableNormalization(aDisableNormalization) {
     21  if (aRealData && aImagData && aRealSize != aImagSize) {
     22    aRv.ThrowIndexSizeError("\"real\" and \"imag\" are different in length");
     23    return;
     24  }
     25 
     26  uint32_t length = 0;
     27  if (aRealData) {
     28    length = aRealSize;
     29  } else if (aImagData) {
     30    length = aImagSize;
     31  } else {
     32    // If nothing has been passed, this PeriodicWave will be a sine wave: 2
     33    // elements for each array, the second imaginary component set to 1.0.
     34    length = 2;
     35  }
     36 
     37  if (length < 2) {
     38    aRv.ThrowIndexSizeError(
     39        "\"real\" and \"imag\" must have a length of "
     40        "at least 2");
     41    return;
     42  }
     43 
     44  MOZ_ASSERT(aContext);
     45  MOZ_ASSERT((aRealData || aImagData) || length == 2);
     46 
     47  // Caller should have checked this and thrown.
     48  MOZ_ASSERT(length >= 2);
     49  mCoefficients.mDuration = length;
     50 
     51  // Copy coefficient data.
     52  // The SharedBuffer and two arrays share a single allocation.
     53  CheckedInt<size_t> bufferSize(sizeof(float));
     54  bufferSize *= length;
     55  bufferSize *= 2;
     56  RefPtr<SharedBuffer> buffer = SharedBuffer::Create(bufferSize, fallible);
     57  if (!buffer) {
     58    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     59    return;
     60  }
     61 
     62  auto data = static_cast<float*>(buffer->Data());
     63  mCoefficients.mBuffer = std::move(buffer);
     64 
     65  if (!aRealData && !aImagData) {
     66    PodZero(data, length);
     67    mCoefficients.mChannelData.AppendElement(data);
     68    data += length;
     69    data[0] = 0.0f;
     70    data[1] = 1.0f;
     71    mCoefficients.mChannelData.AppendElement(data);
     72  } else {
     73    if (aRealData) {
     74      PodCopy(data, aRealData, length);
     75    } else {
     76      PodZero(data, length);
     77    }
     78    mCoefficients.mChannelData.AppendElement(data);
     79 
     80    data += length;
     81    if (aImagData) {
     82      PodCopy(data, aImagData, length);
     83    } else {
     84      PodZero(data, length);
     85    }
     86    mCoefficients.mChannelData.AppendElement(data);
     87  }
     88  mCoefficients.mVolume = 1.0f;
     89  mCoefficients.mBufferFormat = AUDIO_FORMAT_FLOAT32;
     90 }
     91 
     92 /* static */
     93 already_AddRefed<PeriodicWave> PeriodicWave::Constructor(
     94    const GlobalObject& aGlobal, AudioContext& aAudioContext,
     95    const PeriodicWaveOptions& aOptions, ErrorResult& aRv) {
     96  const float* realData;
     97  const float* imagData;
     98  uint32_t realSize;
     99  uint32_t imagSize;
    100 
    101  if (aOptions.mReal.WasPassed()) {
    102    realData = aOptions.mReal.Value().Elements();
    103    realSize = aOptions.mReal.Value().Length();
    104  } else {
    105    realData = nullptr;
    106    realSize = 0;
    107  }
    108 
    109  if (aOptions.mImag.WasPassed()) {
    110    imagData = aOptions.mImag.Value().Elements();
    111    imagSize = aOptions.mImag.Value().Length();
    112  } else {
    113    imagData = nullptr;
    114    imagSize = 0;
    115  }
    116 
    117  RefPtr<PeriodicWave> wave =
    118      new PeriodicWave(&aAudioContext, realData, realSize, imagData, imagSize,
    119                       aOptions.mDisableNormalization, aRv);
    120  if (aRv.Failed()) {
    121    return nullptr;
    122  }
    123 
    124  return wave.forget();
    125 }
    126 
    127 size_t PeriodicWave::SizeOfExcludingThisIfNotShared(
    128    MallocSizeOf aMallocSizeOf) const {
    129  // Not owned:
    130  // - mContext
    131  size_t amount = 0;
    132  amount += mCoefficients.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
    133 
    134  return amount;
    135 }
    136 
    137 size_t PeriodicWave::SizeOfIncludingThisIfNotShared(
    138    MallocSizeOf aMallocSizeOf) const {
    139  return aMallocSizeOf(this) + SizeOfExcludingThisIfNotShared(aMallocSizeOf);
    140 }
    141 
    142 JSObject* PeriodicWave::WrapObject(JSContext* aCx,
    143                                   JS::Handle<JSObject*> aGivenProto) {
    144  return PeriodicWave_Binding::Wrap(aCx, this, aGivenProto);
    145 }
    146 
    147 }  // namespace mozilla::dom