Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/AudioParam.h
Line
Count
Source (jump to first uncovered line)
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 "AudioParamTimeline.h"
11
#include "nsWrapperCache.h"
12
#include "nsCycleCollectionParticipant.h"
13
#include "AudioNode.h"
14
#include "mozilla/dom/TypedArray.h"
15
#include "WebAudioUtils.h"
16
#include "js/TypeDecls.h"
17
18
namespace mozilla {
19
20
namespace dom {
21
22
class AudioParam final : public nsWrapperCache,
23
                         public AudioParamTimeline
24
{
25
  virtual ~AudioParam();
26
27
public:
28
  AudioParam(AudioNode* aNode,
29
             uint32_t aIndex,
30
             const char* aName,
31
             float aDefaultValue,
32
             float aMinValue = std::numeric_limits<float>::lowest(),
33
             float aMaxValue = std::numeric_limits<float>::max());
34
35
  NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
36
  NS_IMETHOD_(MozExternalRefCountType) Release(void);
37
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AudioParam)
38
39
  AudioContext* GetParentObject() const
40
0
  {
41
0
    return mNode->Context();
42
0
  }
43
44
  JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
45
46
  // We override SetValueCurveAtTime to convert the Float32Array to the wrapper
47
  // object.
48
  AudioParam* SetValueCurveAtTime(const nsTArray<float>& aValues,
49
                                  double aStartTime,
50
                                  double aDuration,
51
                                  ErrorResult& aRv)
52
0
  {
53
0
    if (!WebAudioUtils::IsTimeValid(aStartTime)) {
54
0
      aRv.ThrowRangeError<
55
0
        MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
56
0
      return this;
57
0
    }
58
0
    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
59
0
    EventInsertionHelper(aRv, AudioTimelineEvent::SetValueCurve,
60
0
                         aStartTime, 0.0f, 0.0f, aDuration, aValues.Elements(),
61
0
                         aValues.Length());
62
0
63
0
    return this;
64
0
  }
65
66
  void SetValue(float aValue)
67
0
  {
68
0
    AudioTimelineEvent event(AudioTimelineEvent::SetValue, 0.0f, aValue);
69
0
70
0
    ErrorResult rv;
71
0
    if (!ValidateEvent(event, rv)) {
72
0
      MOZ_ASSERT(false, "This should not happen, "
73
0
                        "setting the value should always work");
74
0
      return;
75
0
    }
76
0
77
0
    AudioParamTimeline::SetValue(aValue);
78
0
79
0
    SendEventToEngine(event);
80
0
  }
81
82
  AudioParam* SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
83
0
  {
84
0
    if (!WebAudioUtils::IsTimeValid(aStartTime)) {
85
0
      aRv.ThrowRangeError<
86
0
        MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
87
0
      return this;
88
0
    }
89
0
    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
90
0
    EventInsertionHelper(aRv, AudioTimelineEvent::SetValueAtTime,
91
0
                         aStartTime, aValue);
92
0
93
0
    return this;
94
0
  }
95
96
  AudioParam* LinearRampToValueAtTime(float aValue, double aEndTime,
97
                                      ErrorResult& aRv)
98
0
  {
99
0
    if (!WebAudioUtils::IsTimeValid(aEndTime)) {
100
0
      aRv.ThrowRangeError<
101
0
        MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR>();
102
0
      return this;
103
0
    }
104
0
    aEndTime = std::max(aEndTime, GetParentObject()->CurrentTime());
105
0
    EventInsertionHelper(aRv, AudioTimelineEvent::LinearRamp, aEndTime, aValue);
106
0
    return this;
107
0
  }
108
109
  AudioParam* ExponentialRampToValueAtTime(float aValue, double aEndTime,
110
                                           ErrorResult& aRv)
111
0
  {
112
0
    if (!WebAudioUtils::IsTimeValid(aEndTime)) {
113
0
      aRv.ThrowRangeError<
114
0
        MSG_INVALID_AUDIOPARAM_METHOD_END_TIME_ERROR>();
115
0
      return this;
116
0
    }
117
0
    aEndTime = std::max(aEndTime, GetParentObject()->CurrentTime());
118
0
    EventInsertionHelper(aRv, AudioTimelineEvent::ExponentialRamp,
119
0
                         aEndTime, aValue);
120
0
    return this;
121
0
  }
122
123
  AudioParam* SetTargetAtTime(float aTarget, double aStartTime,
124
                              double aTimeConstant, ErrorResult& aRv)
125
0
  {
126
0
    if (!WebAudioUtils::IsTimeValid(aStartTime) ||
127
0
        !WebAudioUtils::IsTimeValid(aTimeConstant)) {
128
0
      aRv.ThrowRangeError<
129
0
        MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
130
0
      return this;
131
0
    }
132
0
    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
133
0
    EventInsertionHelper(aRv, AudioTimelineEvent::SetTarget,
134
0
                         aStartTime, aTarget,
135
0
                         aTimeConstant);
136
0
137
0
    return this;
138
0
  }
139
140
  AudioParam* CancelScheduledValues(double aStartTime, ErrorResult& aRv)
141
0
  {
142
0
    if (!WebAudioUtils::IsTimeValid(aStartTime)) {
143
0
      aRv.ThrowRangeError<
144
0
        MSG_INVALID_AUDIOPARAM_METHOD_START_TIME_ERROR>();
145
0
      return this;
146
0
    }
147
0
148
0
    aStartTime = std::max(aStartTime, GetParentObject()->CurrentTime());
149
0
150
0
    // Remove some events on the main thread copy.
151
0
    AudioEventTimeline::CancelScheduledValues(aStartTime);
152
0
153
0
    AudioTimelineEvent event(AudioTimelineEvent::Cancel, aStartTime, 0.0f);
154
0
155
0
    SendEventToEngine(event);
156
0
157
0
    return this;
158
0
  }
159
160
  uint32_t ParentNodeId()
161
0
  {
162
0
    return mNode->Id();
163
0
  }
164
165
  void GetName(nsAString& aName)
166
0
  {
167
0
    aName.AssignASCII(mName);
168
0
  }
169
170
  float DefaultValue() const
171
0
  {
172
0
    return mDefaultValue;
173
0
  }
174
175
  float MinValue() const
176
0
  {
177
0
    return mMinValue;
178
0
  }
179
180
  float MaxValue() const
181
0
  {
182
0
    return mMaxValue;
183
0
  }
184
185
  const nsTArray<AudioNode::InputNode>& InputNodes() const
186
  {
187
    return mInputNodes;
188
  }
189
190
  void RemoveInputNode(uint32_t aIndex)
191
  {
192
    mInputNodes.RemoveElementAt(aIndex);
193
  }
194
195
  AudioNode::InputNode* AppendInputNode()
196
  {
197
    return mInputNodes.AppendElement();
198
  }
199
200
  // May create the stream if it doesn't exist
201
  MediaStream* Stream();
202
203
  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
204
  {
205
    size_t amount = AudioParamTimeline::SizeOfExcludingThis(aMallocSizeOf);
206
    // Not owned:
207
    // - mNode
208
209
    // Just count the array, actual nodes are counted in mNode.
210
    amount += mInputNodes.ShallowSizeOfExcludingThis(aMallocSizeOf);
211
212
    if (mNodeStreamPort) {
213
      amount += mNodeStreamPort->SizeOfIncludingThis(aMallocSizeOf);
214
    }
215
216
    return amount;
217
  }
218
219
  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override
220
  {
221
    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
222
  }
223
224
private:
225
  void EventInsertionHelper(ErrorResult& aRv,
226
                            AudioTimelineEvent::Type aType,
227
                            double aTime, float aValue,
228
                            double aTimeConstant = 0.0,
229
                            double aDuration = 0.0,
230
                            const float* aCurve = nullptr,
231
                            uint32_t aCurveLength = 0)
232
0
  {
233
0
    AudioTimelineEvent event(aType, aTime, aValue,
234
0
                             aTimeConstant, aDuration, aCurve, aCurveLength);
235
0
236
0
    if (!ValidateEvent(event, aRv)) {
237
0
      return;
238
0
    }
239
0
240
0
    AudioEventTimeline::InsertEvent<double>(event);
241
0
242
0
    SendEventToEngine(event);
243
0
244
0
    CleanupOldEvents();
245
0
  }
246
247
  void CleanupOldEvents();
248
249
  void SendEventToEngine(const AudioTimelineEvent& aEvent);
250
251
  void DisconnectFromGraphAndDestroyStream();
252
253
  nsCycleCollectingAutoRefCnt mRefCnt;
254
  NS_DECL_OWNINGTHREAD
255
  RefPtr<AudioNode> mNode;
256
  // For every InputNode, there is a corresponding entry in mOutputParams of the
257
  // InputNode's mInputNode.
258
  nsTArray<AudioNode::InputNode> mInputNodes;
259
  const char* mName;
260
  // The input port used to connect the AudioParam's stream to its node's stream
261
  RefPtr<MediaInputPort> mNodeStreamPort;
262
  const uint32_t mIndex;
263
  const float mDefaultValue;
264
  const float mMinValue;
265
  const float mMaxValue;
266
};
267
268
} // namespace dom
269
} // namespace mozilla
270
271
#endif
272