Modules/webaudio/AudioParamTimeline.cpp
Modules/webaudio/AudioProcessingEvent.cpp
Modules/webaudio/AudioScheduledSourceNode.cpp
+ Modules/webaudio/AudioSummingJunction.cpp
Modules/webaudio/BiquadDSPKernel.cpp
Modules/webaudio/BiquadFilterNode.cpp
Modules/webaudio/BiquadProcessor.cpp
+2012-05-15 Chris Rogers <crogers@google.com>
+
+ Add AudioSummingJunction class to handle fan-in (abstracted from AudioNodeInput)
+ https://bugs.webkit.org/show_bug.cgi?id=86396
+
+ Reviewed by Kenneth Russell.
+
+ No new tests. Existing layout tests already extensively test summing.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ Add AudioSummingJunction files to makefiles.
+
+ * Modules/webaudio/AudioContext.cpp:
+ * Modules/webaudio/AudioContext.h:
+ (WebCore::AudioContext::handlePreRenderTasks):
+ (WebCore::AudioContext::handlePostRenderTasks):
+ (WebCore::AudioContext::deleteMarkedNodes):
+ (WebCore::AudioContext::markSummingJunctionDirty):
+ (WebCore::AudioContext::removeMarkedSummingJunction):
+ (WebCore::AudioContext::handleDirtyAudioSummingJunctions):
+ Simple munge from AudioNodeInput -> AudioSummingJunction
+
+ * Modules/webaudio/AudioNodeInput.cpp:
+ * Modules/webaudio/AudioNodeInput.h:
+ (WebCore::AudioNodeInput::AudioNodeInput):
+ (WebCore::AudioNodeInput::didUpdate):
+ Remove logic from AudioNodeInput which now is being moved to AudioSummingJunction.
+
+ * Modules/webaudio/AudioSummingJunction.cpp: Added.
+ * Modules/webaudio/AudioSummingJunction.h: Added.
+ (WebCore::AudioSummingJunction::AudioSummingJunction):
+ (WebCore::AudioSummingJunction::~AudioSummingJunction):
+ (WebCore::AudioSummingJunction::changedOutputs):
+ (WebCore::AudioSummingJunction::updateRenderingState):
+ (WebCore::AudioSummingJunction::context):
+ (WebCore::AudioSummingJunction::numberOfRenderingConnections):
+ (WebCore::AudioSummingJunction::renderingOutput):
+ (WebCore::AudioSummingJunction::isConnected):
+ (WebCore::AudioSummingJunction::numberOfConnections):
+ Add AudioSummingJunction which is an abstraction to manage/track the connections from AudioNodeOutputs
+ representing the fan-in points for unity gain summing junctions.
+
+ * WebCore.gypi:
+ * WebCore.xcodeproj/project.pbxproj:
+ Add AudioSummingJunction files to makefiles.
+
2012-05-15 Dan Bernstein <mitz@apple.com>
Ruby annotation is incorrectly identified as a paragraph boundary
Source/WebCore/Modules/webaudio/AudioProcessingEvent.h \
Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp \
Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h \
+ Source/WebCore/Modules/webaudio/AudioSummingJunction.cpp \
+ Source/WebCore/Modules/webaudio/AudioSummingJunction.h \
Source/WebCore/Modules/webaudio/AudioSourceNode.h \
Source/WebCore/Modules/webaudio/BiquadDSPKernel.cpp \
Source/WebCore/Modules/webaudio/BiquadDSPKernel.h \
// It's OK if the tryLock() fails, we'll just take slightly longer to pick up the changes.
bool mustReleaseLock;
if (tryLock(mustReleaseLock)) {
- // Fixup the state of any dirty AudioNodeInputs and AudioNodeOutputs.
- handleDirtyAudioNodeInputs();
+ // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutputs.
+ handleDirtyAudioSummingJunctions();
handleDirtyAudioNodeOutputs();
updateAutomaticPullNodes();
// Ref-counted objects held by certain AudioNodes may not be thread-safe.
scheduleNodeDeletion();
- // Fixup the state of any dirty AudioNodeInputs and AudioNodeOutputs.
- handleDirtyAudioNodeInputs();
+ // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutputs.
+ handleDirtyAudioSummingJunctions();
handleDirtyAudioNodeOutputs();
updateAutomaticPullNodes();
AudioNode* node = m_nodesToDelete[n - 1];
m_nodesToDelete.removeLast();
- // Before deleting the node, clear out any AudioNodeInputs from m_dirtyAudioNodeInputs.
+ // Before deleting the node, clear out any AudioNodeInputs from m_dirtySummingJunctions.
unsigned numberOfInputs = node->numberOfInputs();
for (unsigned i = 0; i < numberOfInputs; ++i)
- m_dirtyAudioNodeInputs.remove(node->input(i));
+ m_dirtySummingJunctions.remove(node->input(i));
// Before deleting the node, clear out any AudioNodeOutputs from m_dirtyAudioNodeOutputs.
unsigned numberOfOutputs = node->numberOfOutputs();
m_isDeletionScheduled = false;
}
-void AudioContext::markAudioNodeInputDirty(AudioNodeInput* input)
+void AudioContext::markSummingJunctionDirty(AudioSummingJunction* summingJunction)
{
ASSERT(isGraphOwner());
- m_dirtyAudioNodeInputs.add(input);
+ m_dirtySummingJunctions.add(summingJunction);
+}
+
+void AudioContext::removeMarkedSummingJunction(AudioSummingJunction* summingJunction)
+{
+ ASSERT(isMainThread());
+ AutoLocker locker(this);
+ m_dirtySummingJunctions.remove(summingJunction);
}
void AudioContext::markAudioNodeOutputDirty(AudioNodeOutput* output)
m_dirtyAudioNodeOutputs.add(output);
}
-void AudioContext::handleDirtyAudioNodeInputs()
+void AudioContext::handleDirtyAudioSummingJunctions()
{
ASSERT(isGraphOwner());
- for (HashSet<AudioNodeInput*>::iterator i = m_dirtyAudioNodeInputs.begin(); i != m_dirtyAudioNodeInputs.end(); ++i)
+ for (HashSet<AudioSummingJunction*>::iterator i = m_dirtySummingJunctions.begin(); i != m_dirtySummingJunctions.end(); ++i)
(*i)->updateRenderingState();
- m_dirtyAudioNodeInputs.clear();
+ m_dirtySummingJunctions.clear();
}
void AudioContext::handleDirtyAudioNodeOutputs()
class AudioGainNode;
class AudioPannerNode;
class AudioListener;
+class AudioSummingJunction;
class BiquadFilterNode;
class DelayNode;
class Document;
void handleDeferredFinishDerefs();
// Only accessed when the graph lock is held.
- void markAudioNodeInputDirty(AudioNodeInput*);
+ void markSummingJunctionDirty(AudioSummingJunction*);
void markAudioNodeOutputDirty(AudioNodeOutput*);
+ // Must be called on main thread.
+ void removeMarkedSummingJunction(AudioSummingJunction*);
+
// EventTarget
virtual const AtomicString& interfaceName() const;
virtual ScriptExecutionContext* scriptExecutionContext() const;
bool m_isDeletionScheduled;
// Only accessed when the graph lock is held.
- HashSet<AudioNodeInput*> m_dirtyAudioNodeInputs;
+ HashSet<AudioSummingJunction*> m_dirtySummingJunctions;
HashSet<AudioNodeOutput*> m_dirtyAudioNodeOutputs;
- void handleDirtyAudioNodeInputs();
+ void handleDirtyAudioSummingJunctions();
void handleDirtyAudioNodeOutputs();
// For the sake of thread safety, we maintain a seperate Vector of automatic pull nodes for rendering in m_renderingAutomaticPullNodes.
namespace WebCore {
AudioNodeInput::AudioNodeInput(AudioNode* node)
- : m_node(node)
- , m_renderingStateNeedUpdating(false)
+ : AudioSummingJunction(node->context())
+ , m_node(node)
{
// Set to mono by default.
m_internalSummingBus = adoptPtr(new AudioBus(1, AudioNode::ProcessingSizeInFrames));
node()->deref(AudioNode::RefTypeDisabled); // Note: it's important to return immediately after all deref() calls since the node may be deleted.
}
-void AudioNodeInput::changedOutputs()
+void AudioNodeInput::didUpdate()
{
- ASSERT(context()->isGraphOwner());
- if (!m_renderingStateNeedUpdating && !node()->isMarkedForDeletion()) {
- context()->markAudioNodeInputDirty(this);
- m_renderingStateNeedUpdating = true;
- }
-}
-
-void AudioNodeInput::updateRenderingState()
-{
- ASSERT(context()->isAudioThread() && context()->isGraphOwner());
-
- if (m_renderingStateNeedUpdating && !node()->isMarkedForDeletion()) {
- // Copy from m_outputs to m_renderingOutputs.
- m_renderingOutputs.resize(m_outputs.size());
- unsigned j = 0;
- for (HashSet<AudioNodeOutput*>::iterator i = m_outputs.begin(); i != m_outputs.end(); ++i, ++j) {
- AudioNodeOutput* output = *i;
- m_renderingOutputs[j] = output;
- output->updateRenderingState();
- }
-
- node()->checkNumberOfChannelsForInput(this);
-
- m_renderingStateNeedUpdating = false;
- }
+ node()->checkNumberOfChannelsForInput(this);
}
void AudioNodeInput::updateInternalBus()
#include "AudioBus.h"
#include "AudioNode.h"
+#include "AudioSummingJunction.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
// In the case of multiple connections, the input will act as a unity-gain summing junction, mixing all the outputs.
// The number of channels of the input's bus is the maximum of the number of channels of all its connections.
-class AudioNodeInput {
+class AudioNodeInput : public AudioSummingJunction {
public:
AudioNodeInput(AudioNode*);
+ // AudioSummingJunction
+ virtual bool canUpdateState() OVERRIDE { return !node()->isMarkedForDeletion(); }
+ virtual void didUpdate() OVERRIDE;
+
// Can be called from any thread.
AudioNode* node() const { return m_node; }
- AudioContext* context() { return m_node->context(); }
// Must be called with the context's graph lock.
void connect(AudioNodeOutput*);
// Called from context's audio thread.
AudioBus* bus();
- // This copies m_outputs to m_renderingOutputs. Please see comments for these lists below.
- // This must be called when we own the context's graph lock in the audio thread at the very start or end of the render quantum.
- void updateRenderingState();
-
// updateInternalBus() updates m_internalSummingBus appropriately for the number of channels.
// This must be called when we own the context's graph lock in the audio thread at the very start or end of the render quantum.
void updateInternalBus();
- // Rendering code accesses its version of the current connections here.
- unsigned numberOfRenderingConnections() const { return m_renderingOutputs.size(); }
- AudioNodeOutput* renderingOutput(unsigned i) { return m_renderingOutputs[i]; }
- const AudioNodeOutput* renderingOutput(unsigned i) const { return m_renderingOutputs[i]; }
- bool isConnected() const { return numberOfRenderingConnections() > 0; }
-
// The number of channels of the connection with the largest number of channels.
unsigned numberOfChannels() const;
private:
AudioNode* m_node;
- // m_outputs contains the AudioNodeOutputs representing current connections which are not disabled.
- // The rendering code should never use this directly, but instead uses m_renderingOutputs.
- HashSet<AudioNodeOutput*> m_outputs;
-
- // numberOfConnections() should never be called from the audio rendering thread.
- // Instead numberOfRenderingConnections() and renderingOutput() should be used.
- unsigned numberOfConnections() const { return m_outputs.size(); }
-
- // This must be called whenever we modify m_outputs.
- void changedOutputs();
-
- // m_renderingOutputs is a copy of m_outputs which will never be modified during the graph rendering on the audio thread.
- // This is the list which is used by the rendering code.
- // Whenever m_outputs is modified, the context is told so it can later update m_renderingOutputs from m_outputs at a safe time.
- // Most of the time, m_renderingOutputs is identical to m_outputs.
- Vector<AudioNodeOutput*> m_renderingOutputs;
-
- // m_renderingStateNeedUpdating keeps track if m_outputs is modified.
- bool m_renderingStateNeedUpdating;
-
// The number of channels of the rendering connection with the largest number of channels.
unsigned numberOfRenderingChannels();
--- /dev/null
+/*
+ * 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 "AudioSummingJunction.h"
+
+#include "AudioContext.h"
+#include "AudioNodeOutput.h"
+#include <algorithm>
+
+using namespace std;
+
+namespace WebCore {
+
+AudioSummingJunction::AudioSummingJunction(AudioContext* context)
+ : m_context(context)
+ , m_renderingStateNeedUpdating(false)
+{
+}
+
+AudioSummingJunction::~AudioSummingJunction()
+{
+ if (m_renderingStateNeedUpdating && m_context.get())
+ m_context->removeMarkedSummingJunction(this);
+}
+
+void AudioSummingJunction::changedOutputs()
+{
+ ASSERT(context()->isGraphOwner());
+ if (!m_renderingStateNeedUpdating && canUpdateState()) {
+ context()->markSummingJunctionDirty(this);
+ m_renderingStateNeedUpdating = true;
+ }
+}
+
+void AudioSummingJunction::updateRenderingState()
+{
+ ASSERT(context()->isAudioThread() && context()->isGraphOwner());
+
+ if (m_renderingStateNeedUpdating && canUpdateState()) {
+ // Copy from m_outputs to m_renderingOutputs.
+ m_renderingOutputs.resize(m_outputs.size());
+ unsigned j = 0;
+ for (HashSet<AudioNodeOutput*>::iterator i = m_outputs.begin(); i != m_outputs.end(); ++i, ++j) {
+ AudioNodeOutput* output = *i;
+ m_renderingOutputs[j] = output;
+ output->updateRenderingState();
+ }
+
+ didUpdate();
+
+ m_renderingStateNeedUpdating = false;
+ }
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
--- /dev/null
+/*
+ * 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.
+ */
+
+#ifndef AudioSummingJunction_h
+#define AudioSummingJunction_h
+
+#include "AudioBus.h"
+#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AudioContext;
+class AudioNodeOutput;
+
+// An AudioSummingJunction represents a point where zero, one, or more AudioNodeOutputs connect.
+
+class AudioSummingJunction {
+public:
+ AudioSummingJunction(AudioContext*);
+ virtual ~AudioSummingJunction();
+
+ // Can be called from any thread.
+ AudioContext* context() { return m_context.get(); }
+
+ // This must be called whenever we modify m_outputs.
+ void changedOutputs();
+
+ // This copies m_outputs to m_renderingOutputs. Please see comments for these lists below.
+ // This must be called when we own the context's graph lock in the audio thread at the very start or end of the render quantum.
+ void updateRenderingState();
+
+ // Rendering code accesses its version of the current connections here.
+ unsigned numberOfRenderingConnections() const { return m_renderingOutputs.size(); }
+ AudioNodeOutput* renderingOutput(unsigned i) { return m_renderingOutputs[i]; }
+ const AudioNodeOutput* renderingOutput(unsigned i) const { return m_renderingOutputs[i]; }
+ bool isConnected() const { return numberOfRenderingConnections() > 0; }
+
+ virtual bool canUpdateState() = 0;
+ virtual void didUpdate() = 0;
+
+protected:
+ RefPtr<AudioContext> m_context;
+
+ // m_outputs contains the AudioNodeOutputs representing current connections which are not disabled.
+ // The rendering code should never use this directly, but instead uses m_renderingOutputs.
+ HashSet<AudioNodeOutput*> m_outputs;
+
+ // numberOfConnections() should never be called from the audio rendering thread.
+ // Instead numberOfRenderingConnections() and renderingOutput() should be used.
+ unsigned numberOfConnections() const { return m_outputs.size(); }
+
+ // m_renderingOutputs is a copy of m_outputs which will never be modified during the graph rendering on the audio thread.
+ // This is the list which is used by the rendering code.
+ // Whenever m_outputs is modified, the context is told so it can later update m_renderingOutputs from m_outputs at a safe time.
+ // Most of the time, m_renderingOutputs is identical to m_outputs.
+ Vector<AudioNodeOutput*> m_renderingOutputs;
+
+ // m_renderingStateNeedUpdating keeps track if m_outputs is modified.
+ bool m_renderingStateNeedUpdating;
+};
+
+} // namespace WebCore
+
+#endif // AudioSummingJunction_h
'Modules/webaudio/AudioScheduledSourceNode.cpp',
'Modules/webaudio/AudioScheduledSourceNode.h',
'Modules/webaudio/AudioSourceNode.h',
+ 'Modules/webaudio/AudioSummingJunction.cpp',
+ 'Modules/webaudio/AudioSummingJunction.h',
'Modules/webaudio/AsyncAudioDecoder.cpp',
'Modules/webaudio/AsyncAudioDecoder.h',
'Modules/webaudio/BiquadDSPKernel.cpp',
FDA3E95C134A49EF008D4B5A /* OfflineAudioDestinationNode.h in Headers */ = {isa = PBXBuildFile; fileRef = FDA3E958134A49EF008D4B5A /* OfflineAudioDestinationNode.h */; };
FDAF19981513D131008DB0C3 /* DirectConvolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDAF19961513D131008DB0C3 /* DirectConvolver.cpp */; };
FDAF19991513D131008DB0C3 /* DirectConvolver.h in Headers */ = {isa = PBXBuildFile; fileRef = FDAF19971513D131008DB0C3 /* DirectConvolver.h */; };
+ FDB052DF1561A42C00B500D6 /* AudioSummingJunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDB052DD1561A42C00B500D6 /* AudioSummingJunction.cpp */; };
+ FDB052E01561A42C00B500D6 /* AudioSummingJunction.h in Headers */ = {isa = PBXBuildFile; fileRef = FDB052DE1561A42C00B500D6 /* AudioSummingJunction.h */; };
FDB1700514A2BAB200A2B5D9 /* MultiChannelResampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */; };
FDB1700614A2BAB200A2B5D9 /* MultiChannelResampler.h in Headers */ = {isa = PBXBuildFile; fileRef = FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */; };
FDC54F041399B0DA008D9117 /* BiquadFilterNode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */; };
FDA3E95D134A49FF008D4B5A /* OfflineAudioCompletionEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OfflineAudioCompletionEvent.idl; sourceTree = "<group>"; };
FDAF19961513D131008DB0C3 /* DirectConvolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DirectConvolver.cpp; sourceTree = "<group>"; };
FDAF19971513D131008DB0C3 /* DirectConvolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DirectConvolver.h; sourceTree = "<group>"; };
+ FDB052DD1561A42C00B500D6 /* AudioSummingJunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioSummingJunction.cpp; sourceTree = "<group>"; };
+ FDB052DE1561A42C00B500D6 /* AudioSummingJunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioSummingJunction.h; sourceTree = "<group>"; };
FDB1700314A2BAB200A2B5D9 /* MultiChannelResampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiChannelResampler.cpp; sourceTree = "<group>"; };
FDB1700414A2BAB200A2B5D9 /* MultiChannelResampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MultiChannelResampler.h; sourceTree = "<group>"; };
FDC54F011399B0DA008D9117 /* BiquadFilterNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BiquadFilterNode.cpp; sourceTree = "<group>"; };
FD315FD712B0267600C1A359 /* AudioProcessingEvent.idl */,
FD8C46E9154608E700A5910C /* AudioScheduledSourceNode.cpp */,
FD8C46EA154608E700A5910C /* AudioScheduledSourceNode.h */,
+ FDB052DD1561A42C00B500D6 /* AudioSummingJunction.cpp */,
+ FDB052DE1561A42C00B500D6 /* AudioSummingJunction.h */,
FD315FD812B0267600C1A359 /* AudioSourceNode.h */,
FD315FD912B0267600C1A359 /* AudioSourceNode.idl */,
FD315FDA12B0267600C1A359 /* BiquadDSPKernel.cpp */,
B658FFA21522EF3A00DD5595 /* JSRadioNodeList.h in Headers */,
B658FFA61522EFAA00DD5595 /* RadioNodeList.h in Headers */,
29A309B11561CAC400BBD8E5 /* VisitedLinks.h in Headers */,
+ FDB052E01561A42C00B500D6 /* AudioSummingJunction.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B658FFA51522EFAA00DD5595 /* RadioNodeList.cpp in Sources */,
29A309AC1561C99B00BBD8E5 /* RunLoopCF.cpp in Sources */,
29A309B01561CAC400BBD8E5 /* VisitedLinks.cpp in Sources */,
+ FDB052DF1561A42C00B500D6 /* AudioSummingJunction.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};