Title: [115485] trunk/Source/WebCore
Revision
115485
Author
[email protected]
Date
2012-04-27 13:27:43 -0700 (Fri, 27 Apr 2012)

Log Message

Re-factor scheduling logic from AudioBufferSourceNode into AudioScheduledSourceNode
https://bugs.webkit.org/show_bug.cgi?id=84639

Reviewed by Eric Carlson.

Playback logic involving noteOn(), noteOff(), and playbackState were intertwined with
the AudioBufferSourceNode's buffer playback code.  These are more general concepts and
may be implemented separately in another class called AudioScheduledSourceNode.

No new tests. Covered by existing layout tests.

* GNUmakefile.list.am:
Add AudioScheduledSourceNode files to makefile.

* Modules/webaudio/AudioBufferSourceNode.cpp:
(WebCore):
(WebCore::AudioBufferSourceNode::AudioBufferSourceNode):
Re-factor some member variables into new base class AudioScheduledSourceNode.

(WebCore::AudioBufferSourceNode::process):
Re-factor scheduling logic into AudioScheduledSourceNode.

* Modules/webaudio/AudioBufferSourceNode.h:
(AudioBufferSourceNode):
Simplify by re-factoring scheduling logic into AudioScheduledSourceNode.

* Modules/webaudio/AudioScheduledSourceNode.cpp: Added.
(WebCore):
(WebCore::AudioScheduledSourceNode::AudioScheduledSourceNode):
(WebCore::AudioScheduledSourceNode::updateSchedulingInfo):
Get frame information for the current time quantum.

* Modules/webaudio/AudioScheduledSourceNode.h: Added.
(WebCore::AudioScheduledSourceNode::noteOn):
(WebCore::AudioScheduledSourceNode::noteOff):
(WebCore::AudioScheduledSourceNode::finish):
(WebCore::AudioScheduledSourceNode::playbackState):
(WebCore::AudioScheduledSourceNode::isPlayingOrScheduled):
(WebCore::AudioScheduledSourceNode::hasFinished):
Re-factored from AudioBufferSourceNode.

* WebCore.gypi:
* WebCore.xcodeproj/project.pbxproj:
Add AudioScheduledSourceNode files to makefiles.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (115484 => 115485)


--- trunk/Source/WebCore/ChangeLog	2012-04-27 20:23:53 UTC (rev 115484)
+++ trunk/Source/WebCore/ChangeLog	2012-04-27 20:27:43 UTC (rev 115485)
@@ -1,3 +1,50 @@
+2012-04-27  Chris Rogers  <[email protected]>
+
+        Re-factor scheduling logic from AudioBufferSourceNode into AudioScheduledSourceNode
+        https://bugs.webkit.org/show_bug.cgi?id=84639
+
+        Reviewed by Eric Carlson.
+
+        Playback logic involving noteOn(), noteOff(), and playbackState were intertwined with
+        the AudioBufferSourceNode's buffer playback code.  These are more general concepts and
+        may be implemented separately in another class called AudioScheduledSourceNode.
+
+        No new tests. Covered by existing layout tests.
+
+        * GNUmakefile.list.am:
+        Add AudioScheduledSourceNode files to makefile.
+
+        * Modules/webaudio/AudioBufferSourceNode.cpp:
+        (WebCore):
+        (WebCore::AudioBufferSourceNode::AudioBufferSourceNode):
+        Re-factor some member variables into new base class AudioScheduledSourceNode.
+
+        (WebCore::AudioBufferSourceNode::process):
+        Re-factor scheduling logic into AudioScheduledSourceNode.
+
+        * Modules/webaudio/AudioBufferSourceNode.h:
+        (AudioBufferSourceNode):
+        Simplify by re-factoring scheduling logic into AudioScheduledSourceNode.
+
+        * Modules/webaudio/AudioScheduledSourceNode.cpp: Added.
+        (WebCore):
+        (WebCore::AudioScheduledSourceNode::AudioScheduledSourceNode):
+        (WebCore::AudioScheduledSourceNode::updateSchedulingInfo):
+        Get frame information for the current time quantum.
+
+        * Modules/webaudio/AudioScheduledSourceNode.h: Added.
+        (WebCore::AudioScheduledSourceNode::noteOn):
+        (WebCore::AudioScheduledSourceNode::noteOff):
+        (WebCore::AudioScheduledSourceNode::finish):
+        (WebCore::AudioScheduledSourceNode::playbackState):
+        (WebCore::AudioScheduledSourceNode::isPlayingOrScheduled):
+        (WebCore::AudioScheduledSourceNode::hasFinished):
+        Re-factored from AudioBufferSourceNode.
+
+        * WebCore.gypi:
+        * WebCore.xcodeproj/project.pbxproj:
+        Add AudioScheduledSourceNode files to makefiles.
+    
 2012-04-26  Sam Weinig  <[email protected]>
 
         Add support for the Blob constructor

Modified: trunk/Source/WebCore/GNUmakefile.list.am (115484 => 115485)


--- trunk/Source/WebCore/GNUmakefile.list.am	2012-04-27 20:23:53 UTC (rev 115484)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2012-04-27 20:27:43 UTC (rev 115485)
@@ -5505,6 +5505,8 @@
 	Source/WebCore/Modules/webaudio/AudioParamTimeline.h \
 	Source/WebCore/Modules/webaudio/AudioProcessingEvent.cpp \
 	Source/WebCore/Modules/webaudio/AudioProcessingEvent.h \
+	Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp \
+	Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h \
 	Source/WebCore/Modules/webaudio/AudioSourceNode.h \
 	Source/WebCore/Modules/webaudio/BiquadDSPKernel.cpp \
 	Source/WebCore/Modules/webaudio/BiquadDSPKernel.h \

Modified: trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp (115484 => 115485)


--- trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp	2012-04-27 20:23:53 UTC (rev 115484)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp	2012-04-27 20:27:43 UTC (rev 115485)
@@ -43,7 +43,6 @@
 namespace WebCore {
 
 const double DefaultGrainDuration = 0.020; // 20ms
-const double UnknownTime = -1;
 
 // Arbitrary upper limit on playback rate.
 // Higher than expected rates can be useful when playing back oversampled buffers
@@ -56,18 +55,15 @@
 }
 
 AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* context, float sampleRate)
-    : AudioSourceNode(context, sampleRate)
+    : AudioScheduledSourceNode(context, sampleRate)
     , m_buffer(0)
     , m_isLooping(false)
-    , m_startTime(0.0)
-    , m_endTime(UnknownTime)
     , m_virtualReadIndex(0)
     , m_isGrain(false)
     , m_grainOffset(0.0)
     , m_grainDuration(DefaultGrainDuration)
     , m_lastGain(1.0)
     , m_pannerNode(0)
-    , m_playbackState(UNSCHEDULED_STATE)
 {
     setNodeType(NodeTypeAudioBufferSource);
 
@@ -100,37 +96,32 @@
     // The audio thread can't block on this lock, so we call tryLock() instead.
     MutexTryLocker tryLocker(m_processLock);
     if (tryLocker.locked()) {
-        // Check if it's time to start playing.
-        double sampleRate = this->sampleRate();
-        size_t quantumStartFrame = context()->currentSampleFrame();
-        size_t quantumEndFrame = quantumStartFrame + framesToProcess;
-        size_t startFrame = AudioUtilities::timeToSampleFrame(m_startTime, sampleRate);
-        size_t endFrame = m_endTime == UnknownTime ? 0 : AudioUtilities::timeToSampleFrame(m_endTime, sampleRate);
-
-        // If we know the end time and it's already passed, then don't bother doing any more rendering this cycle.
-        if (m_endTime != UnknownTime && endFrame <= quantumStartFrame) {
-            m_virtualReadIndex = 0;
-            finish();
-        }
-        
-        if (m_playbackState == UNSCHEDULED_STATE || m_playbackState == FINISHED_STATE
-            || !buffer() || startFrame >= quantumEndFrame) {
-            // FIXME: can optimize here by propagating silent hint instead of forcing the whole chain to process silence.
+        if (!buffer()) {
             outputBus->zero();
             return;
         }
 
-        if (m_playbackState == SCHEDULED_STATE) {
-            // Increment the active source count only if we're transitioning from SCHEDULED_STATE to PLAYING_STATE.
-            m_playbackState = PLAYING_STATE;
-            context()->incrementActiveSourceCount();
+        size_t quantumStartFrame;
+        size_t quantumEndFrame;
+        size_t startFrame;
+        size_t endFrame;
+        size_t quantumFrameOffset;
+        size_t bufferFramesToProcess;
+
+        updateSchedulingInfo(framesToProcess,
+                             quantumStartFrame,
+                             quantumEndFrame,
+                             startFrame,
+                             endFrame,
+                             quantumFrameOffset,
+                             bufferFramesToProcess);
+                             
+        if (!bufferFramesToProcess) {
+            outputBus->zero();
+            return;
         }
-        
-        size_t quantumFrameOffset = startFrame > quantumStartFrame ? startFrame - quantumStartFrame : 0;
-        quantumFrameOffset = min(quantumFrameOffset, framesToProcess); // clamp to valid range
-        size_t bufferFramesToProcess = framesToProcess - quantumFrameOffset;
 
-        for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i) 
+        for (unsigned i = 0; i < outputBus->numberOfChannels(); ++i)
             m_destinationChannels[i] = outputBus->channel(i)->mutableData();
 
         // Render by reading directly from the buffer.
@@ -347,16 +338,6 @@
     m_lastGain = gain()->value();
 }
 
-void AudioBufferSourceNode::finish()
-{
-    if (m_playbackState != FINISHED_STATE) {
-        // Let the context dereference this AudioNode.
-        context()->notifyNodeFinishedProcessing(this);
-        m_playbackState = FINISHED_STATE;
-        context()->decrementActiveSourceCount();
-    }
-}
-
 bool AudioBufferSourceNode::setBuffer(AudioBuffer* buffer)
 {
     ASSERT(isMainThread());
@@ -394,18 +375,6 @@
     return output(0)->numberOfChannels();
 }
 
-void AudioBufferSourceNode::noteOn(double when)
-{
-    ASSERT(isMainThread());
-    if (m_playbackState != UNSCHEDULED_STATE)
-        return;
-
-    m_isGrain = false;
-    m_startTime = when;
-    m_virtualReadIndex = 0;
-    m_playbackState = SCHEDULED_STATE;
-}
-
 void AudioBufferSourceNode::noteGrainOn(double when, double grainOffset, double grainDuration)
 {
     ASSERT(isMainThread());
@@ -443,16 +412,6 @@
     m_playbackState = SCHEDULED_STATE;
 }
 
-void AudioBufferSourceNode::noteOff(double when)
-{
-    ASSERT(isMainThread());
-    if (!(m_playbackState == SCHEDULED_STATE || m_playbackState == PLAYING_STATE))
-        return;
-    
-    when = max(0.0, when);
-    m_endTime = when;
-}
-
 double AudioBufferSourceNode::totalPitchRate()
 {
     double dopplerRate = 1.0;

Modified: trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h (115484 => 115485)


--- trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h	2012-04-27 20:23:53 UTC (rev 115484)
+++ trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h	2012-04-27 20:27:43 UTC (rev 115485)
@@ -29,7 +29,7 @@
 #include "AudioBus.h"
 #include "AudioGain.h"
 #include "AudioPannerNode.h"
-#include "AudioSourceNode.h"
+#include "AudioScheduledSourceNode.h"
 #include <wtf/OwnArrayPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefPtr.h>
@@ -42,25 +42,8 @@
 // AudioBufferSourceNode is an AudioNode representing an audio source from an in-memory audio asset represented by an AudioBuffer.
 // It generally will be used for short sounds which require a high degree of scheduling flexibility (can playback in rhythmically perfect ways).
 
-class AudioBufferSourceNode : public AudioSourceNode {
-public:
-    // These are the possible states an AudioBufferSourceNode can be in:
-    //
-    // UNSCHEDULED_STATE - Initial playback state. Created, but not yet scheduled.
-    // SCHEDULED_STATE - Scheduled to play (via noteOn() or noteGrainOn()), but not yet playing.
-    // PLAYING_STATE - Generating sound.
-    // FINISHED_STATE - Finished generating sound.
-    //
-    // The state can only transition to the next state, except for the FINISHED_STATE which can
-    // never be changed.
-    enum PlaybackState {
-        // These must be defined with the same names and values as in the .idl file.
-        UNSCHEDULED_STATE = 0,
-        SCHEDULED_STATE = 1,
-        PLAYING_STATE = 2,
-        FINISHED_STATE = 3
-    };
-    
+class AudioBufferSourceNode : public AudioScheduledSourceNode {
+public:    
     static PassRefPtr<AudioBufferSourceNode> create(AudioContext*, float sampleRate);
 
     virtual ~AudioBufferSourceNode();
@@ -80,14 +63,8 @@
                     
     // Play-state
     // noteOn(), noteGrainOn(), and noteOff() must all be called from the main thread.
-    void noteOn(double when);
     void noteGrainOn(double when, double grainOffset, double grainDuration);
-    void noteOff(double when);
 
-    unsigned short playbackState() const { return static_cast<unsigned short>(m_playbackState); }
-    bool isPlayingOrScheduled() const { return m_playbackState == PLAYING_STATE || m_playbackState == SCHEDULED_STATE; }
-    bool hasFinished() const { return m_playbackState == FINISHED_STATE; }
-
     // Note: the attribute was originally exposed as .looping, but to be more consistent in naming with <audio>
     // and with how it's described in the specification, the proper attribute name is .loop
     // The old attribute is kept for backwards compatibility.
@@ -130,14 +107,6 @@
     // If true, it will wrap around to the start of the buffer each time it reaches the end.
     bool m_isLooping;
 
-    // m_startTime is the time to start playing based on the context's timeline (0.0 or a time less than the context's current time means "now").
-    double m_startTime; // in seconds
-
-    // m_endTime is the time to stop playing based on the context's timeline (0.0 or a time less than the context's current time means "now").
-    // If it hasn't been set explicitly, then the sound will not stop playing (if looping) or will stop when the end of the AudioBuffer
-    // has been reached.
-    double m_endTime; // in seconds
-    
     // m_virtualReadIndex is a sample-frame index into our buffer representing the current playback position.
     // Since it's floating-point, it has sub-sample accuracy.
     double m_virtualReadIndex;
@@ -159,11 +128,6 @@
 
     // This synchronizes process() with setBuffer() which can cause dynamic channel count changes.
     mutable Mutex m_processLock;
-
-    // Handles the time when we reach the end of sample data (non-looping) or the noteOff() time has been reached.
-    void finish();
-
-    PlaybackState m_playbackState;
 };
 
 } // namespace WebCore

Added: trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp (0 => 115485)


--- trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp	                        (rev 0)
+++ trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp	2012-04-27 20:27:43 UTC (rev 115485)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2012, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "AudioScheduledSourceNode.h"
+
+#include "AudioContext.h"
+#include "AudioUtilities.h"
+#include <algorithm>
+#include <wtf/MathExtras.h>
+
+using namespace std;
+
+namespace WebCore {
+
+const double AudioScheduledSourceNode::UnknownTime = -1;
+
+AudioScheduledSourceNode::AudioScheduledSourceNode(AudioContext* context, float sampleRate)
+    : AudioSourceNode(context, sampleRate)
+    , m_playbackState(UNSCHEDULED_STATE)
+    , m_startTime(0)
+    , m_endTime(UnknownTime)
+{
+}
+
+void AudioScheduledSourceNode::updateSchedulingInfo(size_t quantumFrameSize,
+                                                    size_t& quantumStartFrame,
+                                                    size_t& quantumEndFrame,
+                                                    size_t& startFrame,
+                                                    size_t& endFrame,
+                                                    size_t& quantumFrameOffset,
+                                                    size_t& nonSilentFramesToProcess)
+{
+    ASSERT(quantumFrameSize == AudioNode::ProcessingSizeInFrames);
+    if (quantumFrameSize != AudioNode::ProcessingSizeInFrames)
+        return;
+    
+    // Check if it's time to start playing.
+    double sampleRate = this->sampleRate();
+    quantumStartFrame = context()->currentSampleFrame();
+    quantumEndFrame = quantumStartFrame + quantumFrameSize;
+    startFrame = AudioUtilities::timeToSampleFrame(m_startTime, sampleRate);
+    endFrame = m_endTime == UnknownTime ? 0 : AudioUtilities::timeToSampleFrame(m_endTime, sampleRate);
+
+    // If we know the end time and it's already passed, then don't bother doing any more rendering this cycle.
+    if (m_endTime != UnknownTime && endFrame <= quantumStartFrame)
+        finish();
+
+    if (m_playbackState == UNSCHEDULED_STATE || m_playbackState == FINISHED_STATE || startFrame >= quantumEndFrame) {
+        // Output silence.
+        nonSilentFramesToProcess = 0;
+        return;
+    }
+
+    if (m_playbackState == SCHEDULED_STATE) {
+        // Increment the active source count only if we're transitioning from SCHEDULED_STATE to PLAYING_STATE.
+        m_playbackState = PLAYING_STATE;
+        context()->incrementActiveSourceCount();
+    }
+
+    quantumFrameOffset = startFrame > quantumStartFrame ? startFrame - quantumStartFrame : 0;
+    quantumFrameOffset = min(quantumFrameOffset, quantumFrameSize); // clamp to valid range
+    nonSilentFramesToProcess = quantumFrameSize - quantumFrameOffset;
+
+    return;
+}
+
+void AudioScheduledSourceNode::noteOn(double when)
+{
+    ASSERT(isMainThread());
+    if (m_playbackState != UNSCHEDULED_STATE)
+        return;
+
+    m_startTime = when;
+    m_playbackState = SCHEDULED_STATE;
+}
+
+void AudioScheduledSourceNode::noteOff(double when)
+{
+    ASSERT(isMainThread());
+    if (!(m_playbackState == SCHEDULED_STATE || m_playbackState == PLAYING_STATE))
+        return;
+    
+    when = max(0.0, when);
+    m_endTime = when;
+}
+
+void AudioScheduledSourceNode::finish()
+{
+    if (m_playbackState != FINISHED_STATE) {
+        // Let the context dereference this AudioNode.
+        context()->notifyNodeFinishedProcessing(this);
+        m_playbackState = FINISHED_STATE;
+        context()->decrementActiveSourceCount();
+    }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)

Added: trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h (0 => 115485)


--- trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h	                        (rev 0)
+++ trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h	2012-04-27 20:27:43 UTC (rev 115485)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AudioScheduledSourceNode_h
+#define AudioScheduledSourceNode_h
+
+#include "AudioSourceNode.h"
+
+namespace WebCore {
+
+class AudioScheduledSourceNode : public AudioSourceNode {
+public:
+    // These are the possible states an AudioScheduledSourceNode can be in:
+    //
+    // UNSCHEDULED_STATE - Initial playback state. Created, but not yet scheduled.
+    // SCHEDULED_STATE - Scheduled to play (via noteOn() or noteGrainOn()), but not yet playing.
+    // PLAYING_STATE - Generating sound.
+    // FINISHED_STATE - Finished generating sound.
+    //
+    // The state can only transition to the next state, except for the FINISHED_STATE which can
+    // never be changed.
+    enum PlaybackState {
+        // These must be defined with the same names and values as in the .idl file.
+        UNSCHEDULED_STATE = 0,
+        SCHEDULED_STATE = 1,
+        PLAYING_STATE = 2,
+        FINISHED_STATE = 3
+    };
+    
+    AudioScheduledSourceNode(AudioContext*, float sampleRate);
+
+    // Scheduling.
+    void noteOn(double when);
+    void noteOff(double when);
+
+    unsigned short playbackState() const { return static_cast<unsigned short>(m_playbackState); }
+    bool isPlayingOrScheduled() const { return m_playbackState == PLAYING_STATE || m_playbackState == SCHEDULED_STATE; }
+    bool hasFinished() const { return m_playbackState == FINISHED_STATE; }
+
+protected:
+    // Get frame information for the current time quantum.
+    // Each frame time is relative to the context's currentSampleFrame().
+    // quantumStartFrame     : Start frame of the current time quantum.
+    // quantumEndFrame       : End frame of the current time quantum.
+    // startFrame            : Start frame for this source.
+    // endFrame              : End frame for this source.
+    // quantumFrameOffset    : Offset frame in this time quantum to start rendering.
+    // nonSilentFramesToProcess : Number of frames rendering non-silence (will be <= quantumFrameSize).
+    void updateSchedulingInfo(size_t quantumFrameSize,
+                              size_t& quantumStartFrame,
+                              size_t& quantumEndFrame,
+                              size_t& startFrame,
+                              size_t& endFrame,
+                              size_t& quantumFrameOffset,
+                              size_t& nonSilentFramesToProcess);
+
+    // Called when we have no more sound to play or the noteOff() time has been reached.
+    void finish();
+
+    PlaybackState m_playbackState;
+
+    // m_startTime is the time to start playing based on the context's timeline (0 or a time less than the context's current time means "now").
+    double m_startTime; // in seconds
+
+    // m_endTime is the time to stop playing based on the context's timeline (0 or a time less than the context's current time means "now").
+    // If it hasn't been set explicitly, then the sound will not stop playing (if looping) or will stop when the end of the AudioBuffer
+    // has been reached.
+    double m_endTime; // in seconds
+
+    static const double UnknownTime;
+};
+
+} // namespace WebCore
+
+#endif // AudioScheduledSourceNode_h

Modified: trunk/Source/WebCore/WebCore.gypi (115484 => 115485)


--- trunk/Source/WebCore/WebCore.gypi	2012-04-27 20:23:53 UTC (rev 115484)
+++ trunk/Source/WebCore/WebCore.gypi	2012-04-27 20:27:43 UTC (rev 115485)
@@ -1591,6 +1591,8 @@
             'Modules/webaudio/AudioParamTimeline.h',
             'Modules/webaudio/AudioProcessingEvent.cpp',
             'Modules/webaudio/AudioProcessingEvent.h',
+            'Modules/webaudio/AudioScheduledSourceNode.cpp',
+            'Modules/webaudio/AudioScheduledSourceNode.h',
             'Modules/webaudio/AudioSourceNode.h',
             'Modules/webaudio/AsyncAudioDecoder.cpp',
             'Modules/webaudio/AsyncAudioDecoder.h',

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (115484 => 115485)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-04-27 20:23:53 UTC (rev 115484)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2012-04-27 20:27:43 UTC (rev 115485)
@@ -6307,6 +6307,8 @@
 		FD7F299713D4C0CB00AD9535 /* WaveShaperProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = FD7F299013D4C0CB00AD9535 /* WaveShaperProcessor.h */; };
 		FD82D7F713D4C8BD004E4372 /* JSWaveShaperNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD82D7F513D4C8BD004E4372 /* JSWaveShaperNode.cpp */; };
 		FD82D7F813D4C8BD004E4372 /* JSWaveShaperNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FD82D7F613D4C8BD004E4372 /* JSWaveShaperNode.h */; };
+		FD8C46EB154608E700A5910C /* AudioScheduledSourceNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD8C46E9154608E700A5910C /* AudioScheduledSourceNode.cpp */; };
+		FD8C46EC154608E700A5910C /* AudioScheduledSourceNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FD8C46EA154608E700A5910C /* AudioScheduledSourceNode.h */; };
 		FD8E9BDF13D4CD2B0050DC72 /* JSWaveShaperNodeCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FD8E9BDE13D4CD2B0050DC72 /* JSWaveShaperNodeCustom.cpp */; };
 		FDA15E9D12B03EE1003A583A /* JSAudioBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDA15E8112B03EE1003A583A /* JSAudioBuffer.cpp */; };
 		FDA15E9E12B03EE1003A583A /* JSAudioBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = FDA15E8212B03EE1003A583A /* JSAudioBuffer.h */; };
@@ -13534,6 +13536,8 @@
 		FD7F299013D4C0CB00AD9535 /* WaveShaperProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WaveShaperProcessor.h; sourceTree = "<group>"; };
 		FD82D7F513D4C8BD004E4372 /* JSWaveShaperNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWaveShaperNode.cpp; sourceTree = "<group>"; };
 		FD82D7F613D4C8BD004E4372 /* JSWaveShaperNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWaveShaperNode.h; sourceTree = "<group>"; };
+		FD8C46E9154608E700A5910C /* AudioScheduledSourceNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioScheduledSourceNode.cpp; sourceTree = "<group>"; };
+		FD8C46EA154608E700A5910C /* AudioScheduledSourceNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioScheduledSourceNode.h; sourceTree = "<group>"; };
 		FD8E9BDE13D4CD2B0050DC72 /* JSWaveShaperNodeCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWaveShaperNodeCustom.cpp; sourceTree = "<group>"; };
 		FDA15E8112B03EE1003A583A /* JSAudioBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAudioBuffer.cpp; sourceTree = "<group>"; };
 		FDA15E8212B03EE1003A583A /* JSAudioBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAudioBuffer.h; sourceTree = "<group>"; };
@@ -21403,6 +21407,8 @@
 				FD315FD512B0267600C1A359 /* AudioProcessingEvent.cpp */,
 				FD315FD612B0267600C1A359 /* AudioProcessingEvent.h */,
 				FD315FD712B0267600C1A359 /* AudioProcessingEvent.idl */,
+				FD8C46E9154608E700A5910C /* AudioScheduledSourceNode.cpp */,
+				FD8C46EA154608E700A5910C /* AudioScheduledSourceNode.h */,
 				FD315FD812B0267600C1A359 /* AudioSourceNode.h */,
 				FD315FD912B0267600C1A359 /* AudioSourceNode.idl */,
 				FD315FDA12B0267600C1A359 /* BiquadDSPKernel.cpp */,
@@ -24823,6 +24829,7 @@
 				E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
 				977E2E0F12F0FC9C00C13379 /* XSSAuditor.h in Headers */,
 				FD537353137B651800008DCE /* ZeroPole.h in Headers */,
+				FD8C46EC154608E700A5910C /* AudioScheduledSourceNode.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -27837,6 +27844,7 @@
 				E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
 				977E2E0E12F0FC9C00C13379 /* XSSAuditor.cpp in Sources */,
 				FD537352137B651800008DCE /* ZeroPole.cpp in Sources */,
+				FD8C46EB154608E700A5910C /* AudioScheduledSourceNode.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to