2 * Copyright (C) 2012 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
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef AudioScheduledSourceNode_h
30 #define AudioScheduledSourceNode_h
32 #include "bindings/core/v8/ActiveScriptWrappable.h"
33 #include "modules/webaudio/AudioSourceNode.h"
37 class BaseAudioContext;
40 class AudioScheduledSourceHandler : public AudioHandler {
42 // These are the possible states an AudioScheduledSourceNode can be in:
44 // UNSCHEDULED_STATE - Initial playback state. Created, but not yet scheduled.
45 // SCHEDULED_STATE - Scheduled to play (via start()), but not yet playing.
46 // PLAYING_STATE - Generating sound.
47 // FINISHED_STATE - Finished generating sound.
49 // The state can only transition to the next state, except for the
50 // FINISHED_STATE which can never be changed.
52 // These must be defined with the same names and values as in the .idl file.
53 UNSCHEDULED_STATE = 0,
59 AudioScheduledSourceHandler(NodeType, AudioNode&, float sampleRate);
62 void start(double when, ExceptionState&);
63 void stop(double when, ExceptionState&);
65 PlaybackState playbackState() const {
66 return static_cast<PlaybackState>(acquireLoad(&m_playbackState));
69 void setPlaybackState(PlaybackState newState) {
70 releaseStore(&m_playbackState, newState);
73 bool isPlayingOrScheduled() const {
74 PlaybackState state = playbackState();
75 return state == PLAYING_STATE || state == SCHEDULED_STATE;
78 bool hasFinished() const { return playbackState() == FINISHED_STATE; }
81 // Get frame information for the current time quantum.
82 // We handle the transition into PLAYING_STATE and FINISHED_STATE here,
83 // zeroing out portions of the outputBus which are outside the range of
84 // startFrame and endFrame.
86 // Each frame time is relative to the context's currentSampleFrame().
87 // quantumFrameOffset : Offset frame in this time quantum to start
89 // nonSilentFramesToProcess : Number of frames rendering non-silence (will be
90 // <= quantumFrameSize).
91 void updateSchedulingInfo(size_t quantumFrameSize,
93 size_t& quantumFrameOffset,
94 size_t& nonSilentFramesToProcess);
96 // Called when we have no more sound to play or the stop() time has been
97 // reached. No onEnded event is called.
98 virtual void finishWithoutOnEnded();
100 // Like finishWithoutOnEnded(), but an onEnded (if specified) is called.
101 virtual void finish();
105 // This synchronizes with process() and any other method that needs to be
106 // synchronized like setBuffer for AudioBufferSource.
107 mutable Mutex m_processLock;
109 // m_startTime is the time to start playing based on the context's timeline (0
110 // or a time less than the context's current time means "now").
111 double m_startTime; // in seconds
113 // m_endTime is the time to stop playing based on the context's timeline (0 or
114 // a time less than the context's current time means "now"). If it hasn't
115 // been set explicitly, then the sound will not stop playing (if looping) or
116 // will stop when the end of the AudioBuffer has been reached.
117 double m_endTime; // in seconds
119 static const double UnknownTime;
122 // This is accessed by both the main thread and audio thread. Use the setter
123 // and getter to protect the access to this.
127 class AudioScheduledSourceNode : public AudioSourceNode,
128 public ActiveScriptWrappable {
129 USING_GARBAGE_COLLECTED_MIXIN(AudioScheduledSourceNode);
132 void start(ExceptionState&);
133 void start(double when, ExceptionState&);
134 void stop(ExceptionState&);
135 void stop(double when, ExceptionState&);
137 EventListener* onended();
138 void setOnended(EventListener*);
141 bool hasPendingActivity() const final;
143 DEFINE_INLINE_VIRTUAL_TRACE() { AudioSourceNode::trace(visitor); }
146 explicit AudioScheduledSourceNode(BaseAudioContext&);
147 AudioScheduledSourceHandler& audioScheduledSourceHandler() const;
152 #endif // AudioScheduledSourceNode_h