16b15388769489016d3029f7c2dd77f185e21951
[platform/framework/web/crosswalk-tizen.git] /
1 /*
2  * Copyright (C) 2010, Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
23  * DAMAGE.
24  */
25
26 #ifndef AudioBufferSourceNode_h
27 #define AudioBufferSourceNode_h
28
29 #include "modules/webaudio/AudioBuffer.h"
30 #include "modules/webaudio/AudioParam.h"
31 #include "modules/webaudio/AudioScheduledSourceNode.h"
32 #include "modules/webaudio/PannerNode.h"
33 #include "platform/audio/AudioBus.h"
34 #include "wtf/PassRefPtr.h"
35 #include "wtf/RefPtr.h"
36 #include "wtf/Threading.h"
37 #include <memory>
38
39 namespace blink {
40
41 class AudioBufferSourceOptions;
42 class BaseAudioContext;
43
44 // AudioBufferSourceNode is an AudioNode representing an audio source from an
45 // in-memory audio asset represented by an AudioBuffer.  It generally will be
46 // used for short sounds which require a high degree of scheduling flexibility
47 // (can playback in rhythmically perfect ways).
48
49 class AudioBufferSourceHandler final : public AudioScheduledSourceHandler {
50  public:
51   static PassRefPtr<AudioBufferSourceHandler> create(
52       AudioNode&,
53       float sampleRate,
54       AudioParamHandler& playbackRate,
55       AudioParamHandler& detune);
56   ~AudioBufferSourceHandler() override;
57
58   // AudioHandler
59   void process(size_t framesToProcess) override;
60
61   // setBuffer() is called on the main thread. This is the buffer we use for
62   // playback.
63   void setBuffer(AudioBuffer*, ExceptionState&);
64   AudioBuffer* buffer() { return m_buffer.get(); }
65
66   // numberOfChannels() returns the number of output channels.  This value
67   // equals the number of channels from the buffer.  If a new buffer is set with
68   // a different number of channels, then this value will dynamically change.
69   unsigned numberOfChannels();
70
71   // Play-state
72   void start(double when, ExceptionState&);
73   void start(double when, double grainOffset, ExceptionState&);
74   void start(double when,
75              double grainOffset,
76              double grainDuration,
77              ExceptionState&);
78
79   // Note: the attribute was originally exposed as |.looping|, but to be more
80   // consistent in naming with <audio> and with how it's described in the
81   // specification, the proper attribute name is |.loop|. The old attribute is
82   // kept for backwards compatibility.
83   bool loop() const { return m_isLooping; }
84   void setLoop(bool looping) {
85     m_isLooping = looping;
86     m_didSetLooping = m_didSetLooping || looping;
87   }
88
89   // Loop times in seconds.
90   double loopStart() const { return m_loopStart; }
91   double loopEnd() const { return m_loopEnd; }
92   void setLoopStart(double loopStart) { m_loopStart = loopStart; }
93   void setLoopEnd(double loopEnd) { m_loopEnd = loopEnd; }
94
95   // If we are no longer playing, propogate silence ahead to downstream nodes.
96   bool propagatesSilence() const override;
97
98   void handleStoppableSourceNode();
99
100  private:
101   AudioBufferSourceHandler(AudioNode&,
102                            float sampleRate,
103                            AudioParamHandler& playbackRate,
104                            AudioParamHandler& detune);
105   void startSource(double when,
106                    double grainOffset,
107                    double grainDuration,
108                    bool isDurationGiven,
109                    ExceptionState&);
110
111   // Returns true on success.
112   bool renderFromBuffer(AudioBus*,
113                         unsigned destinationFrameOffset,
114                         size_t numberOfFrames);
115
116   // Render silence starting from "index" frame in AudioBus.
117   inline bool renderSilenceAndFinishIfNotLooping(AudioBus*,
118                                                  unsigned index,
119                                                  size_t framesToProcess);
120
121   // Clamps grain parameters to the duration of the given AudioBuffer.
122   void clampGrainParameters(const AudioBuffer*);
123
124   // m_buffer holds the sample data which this node outputs.
125   // This Persistent doesn't make a reference cycle including
126   // AudioBufferSourceNode.
127   Persistent<AudioBuffer> m_buffer;
128
129   // Pointers for the buffer and destination.
130   std::unique_ptr<const float* []> m_sourceChannels;
131   std::unique_ptr<float* []> m_destinationChannels;
132
133   RefPtr<AudioParamHandler> m_playbackRate;
134   RefPtr<AudioParamHandler> m_detune;
135
136   // If m_isLooping is false, then this node will be done playing and become
137   // inactive after it reaches the end of the sample data in the buffer.  If
138   // true, it will wrap around to the start of the buffer each time it reaches
139   // the end.
140   bool m_isLooping;
141
142   // True if the source .loop attribute was ever set.
143   bool m_didSetLooping;
144
145   double m_loopStart;
146   double m_loopEnd;
147
148   // m_virtualReadIndex is a sample-frame index into our buffer representing the
149   // current playback position.  Since it's floating-point, it has sub-sample
150   // accuracy.
151   double m_virtualReadIndex;
152
153   // Granular playback
154   bool m_isGrain;
155   double m_grainOffset;    // in seconds
156   double m_grainDuration;  // in seconds
157   // True if grainDuration is given explicitly (via 3 arg start method).
158   bool m_isDurationGiven;
159
160   // Compute playback rate (k-rate) by incorporating the sample rate
161   // conversion factor, and the value of playbackRate and detune AudioParams.
162   double computePlaybackRate();
163
164   // The minimum playbackRate value ever used for this source.
165   double m_minPlaybackRate;
166 };
167
168 class AudioBufferSourceNode final : public AudioScheduledSourceNode {
169   DEFINE_WRAPPERTYPEINFO();
170
171  public:
172   static AudioBufferSourceNode* create(BaseAudioContext&, ExceptionState&);
173   static AudioBufferSourceNode* create(BaseAudioContext*,
174                                        AudioBufferSourceOptions&,
175                                        ExceptionState&);
176   DECLARE_VIRTUAL_TRACE();
177   AudioBufferSourceHandler& audioBufferSourceHandler() const;
178
179   AudioBuffer* buffer() const;
180   void setBuffer(AudioBuffer*, ExceptionState&);
181   AudioParam* playbackRate() const;
182   AudioParam* detune() const;
183   bool loop() const;
184   void setLoop(bool);
185   double loopStart() const;
186   void setLoopStart(double);
187   double loopEnd() const;
188   void setLoopEnd(double);
189
190   void start(ExceptionState&);
191   void start(double when, ExceptionState&);
192   void start(double when, double grainOffset, ExceptionState&);
193   void start(double when,
194              double grainOffset,
195              double grainDuration,
196              ExceptionState&);
197
198  private:
199   AudioBufferSourceNode(BaseAudioContext&);
200
201   Member<AudioParam> m_playbackRate;
202   Member<AudioParam> m_detune;
203 };
204
205 }  // namespace blink
206
207 #endif  // AudioBufferSourceNode_h