2 * Copyright (C) 2010, Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
26 #ifndef AudioBufferSourceNode_h
27 #define AudioBufferSourceNode_h
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"
41 class AudioBufferSourceOptions;
42 class BaseAudioContext;
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).
49 class AudioBufferSourceHandler final : public AudioScheduledSourceHandler {
51 static PassRefPtr<AudioBufferSourceHandler> create(
54 AudioParamHandler& playbackRate,
55 AudioParamHandler& detune);
56 ~AudioBufferSourceHandler() override;
59 void process(size_t framesToProcess) override;
61 // setBuffer() is called on the main thread. This is the buffer we use for
63 void setBuffer(AudioBuffer*, ExceptionState&);
64 AudioBuffer* buffer() { return m_buffer.get(); }
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();
72 void start(double when, ExceptionState&);
73 void start(double when, double grainOffset, ExceptionState&);
74 void start(double when,
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;
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; }
95 // If we are no longer playing, propogate silence ahead to downstream nodes.
96 bool propagatesSilence() const override;
98 void handleStoppableSourceNode();
101 AudioBufferSourceHandler(AudioNode&,
103 AudioParamHandler& playbackRate,
104 AudioParamHandler& detune);
105 void startSource(double when,
107 double grainDuration,
108 bool isDurationGiven,
111 // Returns true on success.
112 bool renderFromBuffer(AudioBus*,
113 unsigned destinationFrameOffset,
114 size_t numberOfFrames);
116 // Render silence starting from "index" frame in AudioBus.
117 inline bool renderSilenceAndFinishIfNotLooping(AudioBus*,
119 size_t framesToProcess);
121 // Clamps grain parameters to the duration of the given AudioBuffer.
122 void clampGrainParameters(const AudioBuffer*);
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;
129 // Pointers for the buffer and destination.
130 std::unique_ptr<const float* []> m_sourceChannels;
131 std::unique_ptr<float* []> m_destinationChannels;
133 RefPtr<AudioParamHandler> m_playbackRate;
134 RefPtr<AudioParamHandler> m_detune;
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
142 // True if the source .loop attribute was ever set.
143 bool m_didSetLooping;
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
151 double m_virtualReadIndex;
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;
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();
164 // The minimum playbackRate value ever used for this source.
165 double m_minPlaybackRate;
168 class AudioBufferSourceNode final : public AudioScheduledSourceNode {
169 DEFINE_WRAPPERTYPEINFO();
172 static AudioBufferSourceNode* create(BaseAudioContext&, ExceptionState&);
173 static AudioBufferSourceNode* create(BaseAudioContext*,
174 AudioBufferSourceOptions&,
176 DECLARE_VIRTUAL_TRACE();
177 AudioBufferSourceHandler& audioBufferSourceHandler() const;
179 AudioBuffer* buffer() const;
180 void setBuffer(AudioBuffer*, ExceptionState&);
181 AudioParam* playbackRate() const;
182 AudioParam* detune() const;
185 double loopStart() const;
186 void setLoopStart(double);
187 double loopEnd() const;
188 void setLoopEnd(double);
190 void start(ExceptionState&);
191 void start(double when, ExceptionState&);
192 void start(double when, double grainOffset, ExceptionState&);
193 void start(double when,
195 double grainDuration,
199 AudioBufferSourceNode(BaseAudioContext&);
201 Member<AudioParam> m_playbackRate;
202 Member<AudioParam> m_detune;
207 #endif // AudioBufferSourceNode_h