content/media/webaudio/DelayBuffer.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/webaudio/DelayBuffer.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,114 @@
     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 +#ifndef DelayBuffer_h_
    1.11 +#define DelayBuffer_h_
    1.12 +
    1.13 +#include "nsTArray.h"
    1.14 +#include "AudioSegment.h"
    1.15 +#include "mozilla/dom/AudioNodeBinding.h" // for ChannelInterpretation
    1.16 +
    1.17 +namespace mozilla {
    1.18 +
    1.19 +class DelayBuffer {
    1.20 +  typedef dom::ChannelInterpretation ChannelInterpretation;
    1.21 +
    1.22 +public:
    1.23 +  // See WebAudioUtils::ComputeSmoothingRate() for frame to frame exponential
    1.24 +  // |smoothingRate| multiplier.
    1.25 +  DelayBuffer(double aMaxDelayTicks, double aSmoothingRate)
    1.26 +    : mSmoothingRate(aSmoothingRate)
    1.27 +    , mCurrentDelay(-1.0)
    1.28 +    // Round the maximum delay up to the next tick.
    1.29 +    , mMaxDelayTicks(ceil(aMaxDelayTicks))
    1.30 +    , mCurrentChunk(0)
    1.31 +    // mLastReadChunk is initialized in EnsureBuffer
    1.32 +#ifdef DEBUG
    1.33 +    , mHaveWrittenBlock(false)
    1.34 +#endif
    1.35 +  {
    1.36 +    // The 180 second limit in AudioContext::CreateDelay() and the
    1.37 +    // 1 << MEDIA_TIME_FRAC_BITS limit on sample rate provide a limit on the
    1.38 +    // maximum delay.
    1.39 +    MOZ_ASSERT(aMaxDelayTicks <=
    1.40 +               std::numeric_limits<decltype(mMaxDelayTicks)>::max());
    1.41 +  }
    1.42 +
    1.43 +  // Write a WEBAUDIO_BLOCK_SIZE block for aChannelCount channels.
    1.44 +  void Write(const AudioChunk& aInputChunk);
    1.45 +
    1.46 +  // Read a block with an array of delays, in ticks, for each sample frame.
    1.47 +  // Each delay should be >= 0 and <= MaxDelayTicks().
    1.48 +  void Read(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
    1.49 +            AudioChunk* aOutputChunk,
    1.50 +            ChannelInterpretation aChannelInterpretation);
    1.51 +  // Read a block with a constant delay, which will be smoothed with the
    1.52 +  // previous delay.  The delay should be >= 0 and <= MaxDelayTicks().
    1.53 +  void Read(double aDelayTicks, AudioChunk* aOutputChunk,
    1.54 +            ChannelInterpretation aChannelInterpretation);
    1.55 +
    1.56 +  // Read into one of the channels of aOutputChunk, given an array of
    1.57 +  // delays in ticks.  This is useful when delays are different on different
    1.58 +  // channels.  aOutputChunk must have already been allocated with at least as
    1.59 +  // many channels as were in any of the blocks passed to Write().
    1.60 +  void ReadChannel(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
    1.61 +                   const AudioChunk* aOutputChunk, uint32_t aChannel,
    1.62 +                   ChannelInterpretation aChannelInterpretation);
    1.63 +
    1.64 +  // Advance the buffer pointer
    1.65 +  void NextBlock()
    1.66 +  {
    1.67 +    mCurrentChunk = (mCurrentChunk + 1) % mChunks.Length();
    1.68 +#ifdef DEBUG
    1.69 +    MOZ_ASSERT(mHaveWrittenBlock);
    1.70 +    mHaveWrittenBlock = false;
    1.71 +#endif
    1.72 +  }
    1.73 +
    1.74 +  void Reset() {
    1.75 +    mChunks.Clear();
    1.76 +    mCurrentDelay = -1.0;
    1.77 +  };
    1.78 +
    1.79 +  int MaxDelayTicks() const { return mMaxDelayTicks; }
    1.80 +
    1.81 +  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
    1.82 +
    1.83 +private:
    1.84 +  void ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
    1.85 +                    const AudioChunk* aOutputChunk,
    1.86 +                    uint32_t aFirstChannel, uint32_t aNumChannelsToRead,
    1.87 +                    ChannelInterpretation aChannelInterpretation);
    1.88 +  bool EnsureBuffer();
    1.89 +  int PositionForDelay(int aDelay);
    1.90 +  int ChunkForPosition(int aPosition);
    1.91 +  int OffsetForPosition(int aPosition);
    1.92 +  int ChunkForDelay(int aDelay);
    1.93 +  void UpdateUpmixChannels(int aNewReadChunk, uint32_t channelCount,
    1.94 +                           ChannelInterpretation aChannelInterpretation);
    1.95 +
    1.96 +  // Circular buffer for capturing delayed samples.
    1.97 +  FallibleTArray<AudioChunk> mChunks;
    1.98 +  // Cache upmixed channel arrays.
    1.99 +  nsAutoTArray<const void*,GUESS_AUDIO_CHANNELS> mUpmixChannels;
   1.100 +  double mSmoothingRate;
   1.101 +  // Current delay, in fractional ticks
   1.102 +  double mCurrentDelay;
   1.103 +  // Maximum delay, in ticks
   1.104 +  int mMaxDelayTicks;
   1.105 +  // The current position in the circular buffer.  The next write will be to
   1.106 +  // this chunk, and the next read may begin before this chunk.
   1.107 +  int mCurrentChunk;
   1.108 +  // The chunk owning the pointers in mUpmixChannels
   1.109 +  int mLastReadChunk;
   1.110 +#ifdef DEBUG
   1.111 +  bool mHaveWrittenBlock;
   1.112 +#endif
   1.113 +};
   1.114 +
   1.115 +} // mozilla
   1.116 +
   1.117 +#endif // DelayBuffer_h_

mercurial