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 AudioBufferSourceNode_h_
8 #define AudioBufferSourceNode_h_
9 
10 #include "AudioScheduledSourceNode.h"
11 #include "AudioBuffer.h"
12 
13 namespace mozilla {
14 namespace dom {
15 
16 struct AudioBufferSourceOptions;
17 class AudioParam;
18 
19 class AudioBufferSourceNode final : public AudioScheduledSourceNode,
20                                     public MainThreadMediaStreamListener {
21  public:
22   static already_AddRefed<AudioBufferSourceNode> Create(
23       JSContext* aCx, AudioContext& aAudioContext,
24       const AudioBufferSourceOptions& aOptions, ErrorResult& aRv);
25 
26   void DestroyMediaStream() override;
27 
NumberOfInputs()28   uint16_t NumberOfInputs() const final { return 0; }
AsAudioBufferSourceNode()29   AudioBufferSourceNode* AsAudioBufferSourceNode() override { return this; }
30   NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode,AudioScheduledSourceNode)31   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioBufferSourceNode,
32                                            AudioScheduledSourceNode)
33 
34   static already_AddRefed<AudioBufferSourceNode> Constructor(
35       const GlobalObject& aGlobal, AudioContext& aAudioContext,
36       const AudioBufferSourceOptions& aOptions, ErrorResult& aRv) {
37     return Create(aGlobal.Context(), aAudioContext, aOptions, aRv);
38   }
39 
40   JSObject* WrapObject(JSContext* aCx,
41                        JS::Handle<JSObject*> aGivenProto) override;
42 
43   void Start(double aWhen, double aOffset, const Optional<double>& aDuration,
44              ErrorResult& aRv);
45 
46   void Start(double aWhen, ErrorResult& aRv) override;
47   void Stop(double aWhen, ErrorResult& aRv) override;
48 
GetBuffer(JSContext * aCx)49   AudioBuffer* GetBuffer(JSContext* aCx) const { return mBuffer; }
SetBuffer(JSContext * aCx,AudioBuffer * aBuffer)50   void SetBuffer(JSContext* aCx, AudioBuffer* aBuffer) {
51     mBuffer = aBuffer;
52     SendBufferParameterToStream(aCx);
53     SendLoopParametersToStream();
54   }
PlaybackRate()55   AudioParam* PlaybackRate() const { return mPlaybackRate; }
Detune()56   AudioParam* Detune() const { return mDetune; }
Loop()57   bool Loop() const { return mLoop; }
SetLoop(bool aLoop)58   void SetLoop(bool aLoop) {
59     mLoop = aLoop;
60     SendLoopParametersToStream();
61   }
LoopStart()62   double LoopStart() const { return mLoopStart; }
SetLoopStart(double aStart)63   void SetLoopStart(double aStart) {
64     mLoopStart = aStart;
65     SendLoopParametersToStream();
66   }
LoopEnd()67   double LoopEnd() const { return mLoopEnd; }
SetLoopEnd(double aEnd)68   void SetLoopEnd(double aEnd) {
69     mLoopEnd = aEnd;
70     SendLoopParametersToStream();
71   }
72   void SendDopplerShiftToStream(double aDopplerShift);
73 
74   void NotifyMainThreadStreamFinished() override;
75 
NodeType()76   const char* NodeType() const override { return "AudioBufferSourceNode"; }
77 
78   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
79   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
80 
81  private:
82   explicit AudioBufferSourceNode(AudioContext* aContext);
83   ~AudioBufferSourceNode() = default;
84 
85   friend class AudioBufferSourceNodeEngine;
86   // START is sent during Start().
87   // STOP is sent during Stop().
88   // BUFFERSTART and BUFFEREND are sent when SetBuffer() and Start() have
89   // been called (along with sending the buffer).
90   enum EngineParameters {
91     SAMPLE_RATE,
92     START,
93     STOP,
94     // BUFFERSTART is the "offset" passed to start(), multiplied by
95     // buffer.sampleRate.
96     BUFFERSTART,
97     // BUFFEREND is the sum of "offset" and "duration" passed to start(),
98     // multiplied by buffer.sampleRate, or the size of the buffer, if smaller.
99     BUFFEREND,
100     LOOP,
101     LOOPSTART,
102     LOOPEND,
103     PLAYBACKRATE,
104     DETUNE,
105     DOPPLERSHIFT
106   };
107 
108   void SendLoopParametersToStream();
109   void SendBufferParameterToStream(JSContext* aCx);
110   void SendOffsetAndDurationParametersToStream(AudioNodeStream* aStream);
111 
112   double mLoopStart;
113   double mLoopEnd;
114   double mOffset;
115   double mDuration;
116   RefPtr<AudioBuffer> mBuffer;
117   RefPtr<AudioParam> mPlaybackRate;
118   RefPtr<AudioParam> mDetune;
119   bool mLoop;
120   bool mStartCalled;
121 };
122 
123 }  // namespace dom
124 }  // namespace mozilla
125 
126 #endif
127