tor-browser

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

AudioParam.h (7420B)


      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 #ifndef AudioParam_h_
      8 #define AudioParam_h_
      9 
     10 #include "AudioNode.h"
     11 #include "AudioParamTimeline.h"
     12 #include "WebAudioUtils.h"
     13 #include "js/TypeDecls.h"
     14 #include "mozilla/ErrorResult.h"
     15 #include "mozilla/dom/TypedArray.h"
     16 #include "nsCycleCollectionParticipant.h"
     17 #include "nsWrapperCache.h"
     18 
     19 namespace mozilla::dom {
     20 
     21 class AudioParam final : public nsWrapperCache, public AudioParamTimeline {
     22  virtual ~AudioParam();
     23 
     24 public:
     25  AudioParam(AudioNode* aNode, uint32_t aIndex, const nsAString& aName,
     26             float aDefaultValue,
     27             float aMinValue = std::numeric_limits<float>::lowest(),
     28             float aMaxValue = std::numeric_limits<float>::max());
     29 
     30  NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
     31  NS_IMETHOD_(MozExternalRefCountType) Release(void);
     32  NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(AudioParam)
     33 
     34  AudioContext* GetParentObject() const { return mNode->Context(); }
     35 
     36  JSObject* WrapObject(JSContext* aCx,
     37                       JS::Handle<JSObject*> aGivenProto) override;
     38 
     39  float Value() {
     40    return AudioParamTimeline::GetValueAtTime<double>(
     41        GetParentObject()->CurrentTime());
     42  }
     43 
     44  // We override SetValueCurveAtTime to convert the Float32Array to the wrapper
     45  // object.
     46  AudioParam* SetValueCurveAtTime(const nsTArray<float>& aValues,
     47                                  double aStartTime, double aDuration,
     48                                  ErrorResult& aRv) {
     49    if (!WebAudioUtils::IsTimeValid(aStartTime)) {
     50      aRv.ThrowRangeError<MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
     51      return this;
     52    }
     53    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
     54    AudioParamEvent event(AudioTimelineEvent::SetValueCurve, aValues,
     55                          aStartTime, aDuration);
     56    ValidateAndInsertEvent(event, aRv);
     57    return this;
     58  }
     59 
     60  // Intended for use in AudioNode creation, when the setter should not throw.
     61  void SetInitialValue(float aValue) {
     62    IgnoredErrorResult rv;
     63    SetValue(aValue, rv);
     64  }
     65 
     66  void SetValue(float aValue, ErrorResult& aRv) {
     67    SetValueAtTime(aValue, GetParentObject()->CurrentTime(), aRv);
     68  }
     69 
     70  AudioParam* SetValueAtTime(float aValue, double aStartTime,
     71                             ErrorResult& aRv) {
     72    if (!WebAudioUtils::IsTimeValid(aStartTime)) {
     73      aRv.ThrowRangeError<MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
     74      return this;
     75    }
     76    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
     77    AudioParamEvent event(AudioTimelineEvent::SetValueAtTime, aStartTime,
     78                          aValue);
     79    ValidateAndInsertEvent(event, aRv);
     80    return this;
     81  }
     82 
     83  AudioParam* LinearRampToValueAtTime(float aValue, double aEndTime,
     84                                      ErrorResult& aRv) {
     85    if (!WebAudioUtils::IsTimeValid(aEndTime)) {
     86      aRv.ThrowRangeError<MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR>();
     87      return this;
     88    }
     89    aEndTime = std::max(aEndTime, GetParentObject()->CurrentTime());
     90    AudioParamEvent event(AudioTimelineEvent::LinearRamp, aEndTime, aValue);
     91    ValidateAndInsertEvent(event, aRv);
     92    return this;
     93  }
     94 
     95  AudioParam* ExponentialRampToValueAtTime(float aValue, double aEndTime,
     96                                           ErrorResult& aRv) {
     97    if (!WebAudioUtils::IsTimeValid(aEndTime)) {
     98      aRv.ThrowRangeError<MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR>();
     99      return this;
    100    }
    101    aEndTime = std::max(aEndTime, GetParentObject()->CurrentTime());
    102    AudioParamEvent event(AudioTimelineEvent::ExponentialRamp, aEndTime,
    103                          aValue);
    104    ValidateAndInsertEvent(event, aRv);
    105    return this;
    106  }
    107 
    108  AudioParam* SetTargetAtTime(float aTarget, double aStartTime,
    109                              double aTimeConstant, ErrorResult& aRv) {
    110    if (!WebAudioUtils::IsTimeValid(aStartTime) ||
    111        !WebAudioUtils::IsTimeValid(aTimeConstant)) {
    112      aRv.ThrowRangeError<MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
    113      return this;
    114    }
    115    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
    116    AudioParamEvent event(AudioTimelineEvent::SetTarget, aStartTime, aTarget,
    117                          aTimeConstant);
    118    ValidateAndInsertEvent(event, aRv);
    119    return this;
    120  }
    121 
    122  AudioParam* CancelScheduledValues(double aStartTime, ErrorResult& aRv) {
    123    if (!WebAudioUtils::IsTimeValid(aStartTime)) {
    124      aRv.ThrowRangeError<MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
    125      return this;
    126    }
    127 
    128    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
    129 
    130    // Remove some events on the main thread copy.
    131    AudioEventTimeline::CancelScheduledValues(aStartTime);
    132 
    133    AudioParamEvent event(AudioTimelineEvent::Cancel, aStartTime, 0.0f);
    134 
    135    SendEventToEngine(event);
    136 
    137    return this;
    138  }
    139 
    140  uint32_t ParentNodeId() { return mNode->Id(); }
    141 
    142  void GetName(nsAString& aName) { aName.Assign(mName); }
    143 
    144  float DefaultValue() const { return mDefaultValue; }
    145 
    146  float MinValue() const { return mMinValue; }
    147 
    148  float MaxValue() const { return mMaxValue; }
    149 
    150  bool IsTrackSuspended() const {
    151    return mTrack ? mTrack->IsSuspended() : false;
    152  }
    153 
    154  const nsTArray<AudioNode::InputNode>& InputNodes() const {
    155    return mInputNodes;
    156  }
    157 
    158  void RemoveInputNode(uint32_t aIndex) { mInputNodes.RemoveElementAt(aIndex); }
    159 
    160  AudioNode::InputNode* AppendInputNode() {
    161    return mInputNodes.AppendElement();
    162  }
    163 
    164  // May create the track if it doesn't exist
    165  mozilla::MediaTrack* Track();
    166 
    167  // Return nullptr if track doesn't exist.
    168  mozilla::MediaTrack* GetTrack() const;
    169 
    170  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override {
    171    size_t amount = AudioParamTimeline::SizeOfExcludingThis(aMallocSizeOf);
    172    // Not owned:
    173    // - mNode
    174 
    175    // Just count the array, actual nodes are counted in mNode.
    176    amount += mInputNodes.ShallowSizeOfExcludingThis(aMallocSizeOf);
    177 
    178    if (mNodeTrackPort) {
    179      amount += mNodeTrackPort->SizeOfIncludingThis(aMallocSizeOf);
    180    }
    181 
    182    return amount;
    183  }
    184 
    185  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override {
    186    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
    187  }
    188 
    189 private:
    190  void ValidateAndInsertEvent(const AudioParamEvent& aEvent, ErrorResult& aRv) {
    191    if (!ValidateEvent(aEvent, aRv)) {
    192      return;
    193    }
    194 
    195    AudioEventTimeline::InsertEvent<double>(aEvent);
    196 
    197    SendEventToEngine(aEvent);
    198 
    199    CleanupOldEvents();
    200  }
    201 
    202  void CleanupOldEvents();
    203 
    204  void SendEventToEngine(const AudioParamEvent& aEvent);
    205 
    206  void DisconnectFromGraphAndDestroyTrack();
    207 
    208  nsCycleCollectingAutoRefCnt mRefCnt;
    209  NS_DECL_OWNINGTHREAD
    210  RefPtr<AudioNode> mNode;
    211  // For every InputNode, there is a corresponding entry in mOutputParams of the
    212  // InputNode's mInputNode.
    213  nsTArray<AudioNode::InputNode> mInputNodes;
    214  const nsString mName;
    215  // The input port used to connect the AudioParam's track to its node's track
    216  RefPtr<MediaInputPort> mNodeTrackPort;
    217  const uint32_t mIndex;
    218  const float mDefaultValue;
    219  const float mMinValue;
    220  const float mMaxValue;
    221 };
    222 
    223 }  // namespace mozilla::dom
    224 
    225 #endif