tor-browser

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

RLBoxSoundTouch.cpp (5574B)


      1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "mozilla/Assertions.h"
      7 #include "RLBoxSoundTouch.h"
      8 
      9 using namespace rlbox;
     10 using namespace mozilla;
     11 using namespace soundtouch;
     12 
     13 RLBoxSoundTouch::RLBoxSoundTouch() {}
     14 
     15 bool RLBoxSoundTouch::Init() {
     16 #ifdef MOZ_WASM_SANDBOXING_SOUNDTOUCH
     17  const bool success = mSandbox.create_sandbox(
     18    /* shouldAbortOnFailure = */ false,
     19    /* custom capacity = */ nullptr,
     20    "rlbox_wasm2c_soundtouch");
     21 #else
     22  const bool success = true;
     23  mSandbox.create_sandbox();
     24 #endif
     25 
     26  if (!success){
     27    return false;
     28  }
     29 
     30  mTimeStretcher = mSandbox.invoke_sandbox_function(createSoundTouchObj);
     31 
     32  // Allocate buffer in sandbox to receive samples.
     33  mSampleBuffer = mSandbox.malloc_in_sandbox<AudioDataValue>(mSampleBufferSize);
     34  MOZ_RELEASE_ASSERT(mSampleBuffer);
     35  mCreated = true;
     36  return true;
     37 }
     38 
     39 RLBoxSoundTouch::~RLBoxSoundTouch() {
     40  if (mCreated) {
     41    mSandbox.free_in_sandbox(mSampleBuffer);
     42    mSandbox.invoke_sandbox_function(destroySoundTouchObj, mTimeStretcher);
     43    mTimeStretcher = nullptr;
     44    mSandbox.destroy_sandbox();
     45  }
     46 }
     47 
     48 void RLBoxSoundTouch::setSampleRate(uint aRate) {
     49  mSandbox.invoke_sandbox_function(SetSampleRate, mTimeStretcher, aRate);
     50 }
     51 
     52 void RLBoxSoundTouch::setChannels(uint aChannels) {
     53  mChannels = aChannels;
     54  mSandbox.invoke_sandbox_function(SetChannels, mTimeStretcher, aChannels);
     55 }
     56 
     57 void RLBoxSoundTouch::setPitch(double aPitch) {
     58  mSandbox.invoke_sandbox_function(SetPitch, mTimeStretcher, aPitch);
     59 }
     60 
     61 void RLBoxSoundTouch::setSetting(int aSettingId, int aValue) {
     62  mSandbox.invoke_sandbox_function(SetSetting, mTimeStretcher, aSettingId,
     63                                   aValue);
     64 }
     65 
     66 void RLBoxSoundTouch::setTempo(double aTempo) {
     67  mSandbox.invoke_sandbox_function(SetTempo, mTimeStretcher, aTempo);
     68 }
     69 
     70 void RLBoxSoundTouch::setRate(double aRate) {
     71  mSandbox.invoke_sandbox_function(SetRate, mTimeStretcher, aRate);
     72 }
     73 
     74 uint RLBoxSoundTouch::numChannels() {
     75  auto numChannels = mChannels;
     76  mSandbox.invoke_sandbox_function(NumChannels, mTimeStretcher)
     77      .copy_and_verify([numChannels](auto ch) {
     78        MOZ_RELEASE_ASSERT(ch == numChannels, "Number of channels changed");
     79      });
     80  return mChannels;
     81 }
     82 
     83 tainted_soundtouch<uint> RLBoxSoundTouch::numSamples() {
     84  return mSandbox.invoke_sandbox_function(NumSamples, mTimeStretcher);
     85 }
     86 
     87 tainted_soundtouch<uint> RLBoxSoundTouch::numUnprocessedSamples() {
     88  return mSandbox.invoke_sandbox_function(NumUnprocessedSamples,
     89                                          mTimeStretcher);
     90 }
     91 
     92 void RLBoxSoundTouch::putSamples(const AudioDataValue* aSamples,
     93                                 uint aNumSamples) {
     94  const CheckedInt<size_t> nrTotalSamples = numChannels() * aNumSamples;
     95  MOZ_RELEASE_ASSERT(nrTotalSamples.isValid(), "Input buffer size overflow");
     96 
     97  bool copied = false;
     98  auto t_aSamples = copy_memory_or_grant_access(
     99      mSandbox, aSamples, nrTotalSamples.value(), false, copied);
    100 
    101  mSandbox.invoke_sandbox_function(PutSamples, mTimeStretcher, t_aSamples,
    102                                   aNumSamples);
    103 
    104  if (copied) {
    105    mSandbox.free_in_sandbox(t_aSamples);
    106  }
    107 }
    108 
    109 uint RLBoxSoundTouch::receiveSamples(AudioDataValue* aOutput,
    110                                     uint aMaxSamples) {
    111  // Check number of channels.
    112  const CheckedInt<uint> channels = numChannels();
    113  // Sanity check max samples.
    114  const CheckedInt<uint> maxElements = channels * aMaxSamples;
    115  MOZ_RELEASE_ASSERT(maxElements.isValid(), "Max number of elements overflow");
    116 
    117  // Check mSampleBuffer size, and resize if required.
    118  if (mSampleBufferSize < maxElements.value()) {
    119    resizeSampleBuffer(maxElements.value());
    120  }
    121 
    122  auto numWrittenSamples =
    123      mSandbox
    124          .invoke_sandbox_function(ReceiveSamples, mTimeStretcher,
    125                                   mSampleBuffer, aMaxSamples)
    126          .copy_and_verify([aMaxSamples](uint written) {
    127            MOZ_RELEASE_ASSERT(written <= aMaxSamples,
    128                               "Number of samples exceeds max samples");
    129            return written;
    130          });
    131 
    132  // Copy received elements from sandbox.
    133  if (numWrittenSamples > 0) {
    134    const CheckedInt<uint> numCopyElements = channels * numWrittenSamples;
    135 
    136    MOZ_RELEASE_ASSERT(numCopyElements.isValid() &&
    137                           numCopyElements.value() <= maxElements.value(),
    138                       "Bad number of written elements");
    139 
    140    // Get pointer to mSampleBuffer. RLBox ensures that we have at least
    141    // numCopyElements elements.  We are just copying data values out. These
    142    // values are untrusted but should only be interpreted as sound samples --
    143    // so should, at worst, just sound weird.
    144    auto* mSampleBuffer_ptr = mSampleBuffer.unverified_safe_pointer_because(
    145        numCopyElements.value(),
    146        "Pointer to buffer is within sandbox and has at least numCopyElements "
    147        "elements.");
    148    PodCopy(aOutput, mSampleBuffer_ptr, numCopyElements.value());
    149  }
    150 
    151  return numWrittenSamples;
    152 }
    153 
    154 void RLBoxSoundTouch::flush() {
    155  return mSandbox.invoke_sandbox_function(Flush, mTimeStretcher);
    156 }
    157 
    158 void RLBoxSoundTouch::resizeSampleBuffer(uint aNewSize) {
    159  mSandbox.free_in_sandbox(mSampleBuffer);
    160  mSampleBufferSize = aNewSize;
    161  mSampleBuffer = mSandbox.malloc_in_sandbox<AudioDataValue>(aNewSize);
    162  MOZ_RELEASE_ASSERT(mSampleBuffer);
    163 }