DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (56e7b9127e89)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef AudioParamTimeline_h_
#define AudioParamTimeline_h_

#include "AudioEventTimeline.h"
#include "mozilla/ErrorResult.h"
#include "MediaStreamGraph.h"
#include "AudioSegment.h"

namespace mozilla {

namespace dom {

// This helper class is used to represent the part of the AudioParam
// class that gets sent to AudioNodeEngine instances.  In addition to
// AudioEventTimeline methods, it holds a pointer to an optional
// MediaStream which represents the AudioNode inputs to the AudioParam.
// This MediaStream is managed by the AudioParam subclass on the main
// thread, and can only be obtained from the AudioNodeEngine instances
// consuming this class.
class AudioParamTimeline : public AudioEventTimeline
{
  typedef AudioEventTimeline BaseClass;

public:
  explicit AudioParamTimeline(float aDefaultValue)
    : BaseClass(aDefaultValue)
  {
  }

  MediaStream* Stream() const
  {
    return mStream;
  }

  bool HasSimpleValue() const
  {
    return BaseClass::HasSimpleValue() && !mStream;
  }

  template<class TimeType>
  float GetValueAtTime(TimeType aTime)
  {
    return GetValueAtTime(aTime, 0);
  }

  template<typename TimeType>
  void InsertEvent(const AudioTimelineEvent& aEvent)
  {
    if (aEvent.mType == AudioTimelineEvent::Cancel) {
      CancelScheduledValues(aEvent.template Time<TimeType>());
      return;
    }
    if (aEvent.mType == AudioTimelineEvent::Stream) {
      mStream = aEvent.mStream;
      return;
    }
    if (aEvent.mType == AudioTimelineEvent::SetValue) {
      AudioEventTimeline::SetValue(aEvent.mValue);
      return;
    }
    AudioEventTimeline::InsertEvent<TimeType>(aEvent);
  }

  // Get the value of the AudioParam at time aTime + aCounter.
  // aCounter here is an offset to aTime if we try to get the value in ticks,
  // otherwise it should always be zero.  aCounter is meant to be used when
  template<class TimeType>
  float GetValueAtTime(TimeType aTime, size_t aCounter);

  // Get the values of the AudioParam at time aTime + (0 to aSize).
  // aBuffer must have the correct aSize.
  // aSize here is an offset to aTime if we try to get the value in ticks,
  // otherwise it should always be zero.  aSize is meant to be used when
  // getting the value of an a-rate AudioParam for each tick inside an
  // AudioNodeEngine implementation.
  template<class TimeType>
  void GetValuesAtTime(TimeType aTime, float* aBuffer, const size_t aSize);

  virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
  {
    return mStream ? mStream->SizeOfIncludingThis(aMallocSizeOf) : 0;
  }

  virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
  {
    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
  }


private:
  float AudioNodeInputValue(size_t aCounter) const;

protected:
  // This is created lazily when needed.
  RefPtr<MediaStream> mStream;
};

template<> inline float
AudioParamTimeline::GetValueAtTime(double aTime, size_t aCounter)
{
  MOZ_ASSERT(!aCounter);

  // Getting an AudioParam value on an AudioNode does not consider input from
  // other AudioNodes, which is managed only on the graph thread.
  return BaseClass::GetValueAtTime(aTime);
}

template<> inline float
AudioParamTimeline::GetValueAtTime(int64_t aTime, size_t aCounter)
{
  MOZ_ASSERT(aCounter < WEBAUDIO_BLOCK_SIZE);
  MOZ_ASSERT(!aCounter || !HasSimpleValue());

  // Mix the value of the AudioParam itself with that of the AudioNode inputs.
  return BaseClass::GetValueAtTime(static_cast<int64_t>(aTime + aCounter)) +
    (mStream ? AudioNodeInputValue(aCounter) : 0.0f);
}

template<> inline void
AudioParamTimeline::GetValuesAtTime(double aTime, float* aBuffer,
                                    const size_t aSize)
{
  MOZ_ASSERT(aBuffer);
  MOZ_ASSERT(aSize == 1);

  // Getting an AudioParam value on an AudioNode does not consider input from
  // other AudioNodes, which is managed only on the graph thread.
  *aBuffer = BaseClass::GetValueAtTime(aTime);
}

template<> inline void
AudioParamTimeline::GetValuesAtTime(int64_t aTime, float* aBuffer,
                                    const size_t aSize)
{
  MOZ_ASSERT(aBuffer);
  MOZ_ASSERT(aSize <= WEBAUDIO_BLOCK_SIZE);
  MOZ_ASSERT(aSize == 1 || !HasSimpleValue());

  // Mix the value of the AudioParam itself with that of the AudioNode inputs.
  BaseClass::GetValuesAtTime(aTime, aBuffer, aSize);
  if (mStream) {
    uint32_t blockOffset = aTime % WEBAUDIO_BLOCK_SIZE;
    MOZ_ASSERT(blockOffset + aSize <= WEBAUDIO_BLOCK_SIZE);
    for (size_t i = 0; i < aSize; ++i) {
      aBuffer[i] += AudioNodeInputValue(blockOffset + i);
    }
  }
}

} // namespace dom
} // namespace mozilla

#endif