From cad810f21b803229eb11403f9209855525a25d57 Mon Sep 17 00:00:00 2001 From: Steve Block Date: Fri, 6 May 2011 11:45:16 +0100 Subject: Merge WebKit at r75315: Initial merge by git. Change-Id: I570314b346ce101c935ed22a626b48c2af266b84 --- WebCore/webaudio/AudioBasicProcessorNode.cpp | 149 -------- WebCore/webaudio/AudioBasicProcessorNode.h | 68 ---- WebCore/webaudio/AudioBuffer.cpp | 110 ------ WebCore/webaudio/AudioBuffer.h | 81 ---- WebCore/webaudio/AudioBuffer.idl | 43 --- WebCore/webaudio/AudioBufferSourceNode.cpp | 455 ----------------------- WebCore/webaudio/AudioBufferSourceNode.h | 147 -------- WebCore/webaudio/AudioBufferSourceNode.idl | 41 --- WebCore/webaudio/AudioChannelMerger.cpp | 102 ------ WebCore/webaudio/AudioChannelMerger.h | 56 --- WebCore/webaudio/AudioChannelMerger.idl | 34 -- WebCore/webaudio/AudioChannelSplitter.cpp | 84 ----- WebCore/webaudio/AudioChannelSplitter.h | 52 --- WebCore/webaudio/AudioChannelSplitter.idl | 30 -- WebCore/webaudio/AudioContext.cpp | 529 --------------------------- WebCore/webaudio/AudioContext.h | 259 ------------- WebCore/webaudio/AudioContext.idl | 64 ---- WebCore/webaudio/AudioDestinationNode.cpp | 114 ------ WebCore/webaudio/AudioDestinationNode.h | 72 ---- WebCore/webaudio/AudioDestinationNode.idl | 32 -- WebCore/webaudio/AudioGain.h | 53 --- WebCore/webaudio/AudioGain.idl | 35 -- WebCore/webaudio/AudioGainNode.cpp | 113 ------ WebCore/webaudio/AudioGainNode.h | 70 ---- WebCore/webaudio/AudioGainNode.idl | 33 -- WebCore/webaudio/AudioListener.cpp | 51 --- WebCore/webaudio/AudioListener.h | 94 ----- WebCore/webaudio/AudioListener.idl | 40 -- WebCore/webaudio/AudioNode.cpp | 317 ---------------- WebCore/webaudio/AudioNode.h | 171 --------- WebCore/webaudio/AudioNode.idl | 39 -- WebCore/webaudio/AudioNodeInput.cpp | 270 -------------- WebCore/webaudio/AudioNodeInput.h | 125 ------- WebCore/webaudio/AudioNodeOutput.cpp | 216 ----------- WebCore/webaudio/AudioNodeOutput.h | 134 ------- WebCore/webaudio/AudioPannerNode.cpp | 317 ---------------- WebCore/webaudio/AudioPannerNode.h | 148 -------- WebCore/webaudio/AudioPannerNode.idl | 59 --- WebCore/webaudio/AudioParam.cpp | 66 ---- WebCore/webaudio/AudioParam.h | 100 ----- WebCore/webaudio/AudioParam.idl | 43 --- WebCore/webaudio/AudioProcessingEvent.cpp | 59 --- WebCore/webaudio/AudioProcessingEvent.h | 57 --- WebCore/webaudio/AudioProcessingEvent.idl | 33 -- WebCore/webaudio/AudioSourceNode.h | 46 --- WebCore/webaudio/AudioSourceNode.idl | 34 -- WebCore/webaudio/BiquadDSPKernel.cpp | 77 ---- WebCore/webaudio/BiquadDSPKernel.h | 56 --- WebCore/webaudio/BiquadProcessor.cpp | 125 ------- WebCore/webaudio/BiquadProcessor.h | 78 ---- WebCore/webaudio/ConvolverNode.cpp | 152 -------- WebCore/webaudio/ConvolverNode.h | 69 ---- WebCore/webaudio/ConvolverNode.idl | 33 -- WebCore/webaudio/DelayDSPKernel.cpp | 140 ------- WebCore/webaudio/DelayDSPKernel.h | 62 ---- WebCore/webaudio/DelayNode.cpp | 47 --- WebCore/webaudio/DelayNode.h | 53 --- WebCore/webaudio/DelayNode.idl | 32 -- WebCore/webaudio/DelayProcessor.cpp | 54 --- WebCore/webaudio/DelayProcessor.h | 53 --- WebCore/webaudio/HighPass2FilterNode.cpp | 42 --- WebCore/webaudio/HighPass2FilterNode.h | 53 --- WebCore/webaudio/HighPass2FilterNode.idl | 35 -- WebCore/webaudio/JavaScriptAudioNode.cpp | 272 -------------- WebCore/webaudio/JavaScriptAudioNode.h | 104 ------ WebCore/webaudio/JavaScriptAudioNode.idl | 40 -- WebCore/webaudio/LowPass2FilterNode.cpp | 42 --- WebCore/webaudio/LowPass2FilterNode.h | 53 --- WebCore/webaudio/LowPass2FilterNode.idl | 35 -- WebCore/webaudio/RealtimeAnalyser.cpp | 301 --------------- WebCore/webaudio/RealtimeAnalyser.h | 103 ------ WebCore/webaudio/RealtimeAnalyserNode.cpp | 88 ----- WebCore/webaudio/RealtimeAnalyserNode.h | 76 ---- WebCore/webaudio/RealtimeAnalyserNode.idl | 48 --- 74 files changed, 7568 deletions(-) delete mode 100644 WebCore/webaudio/AudioBasicProcessorNode.cpp delete mode 100644 WebCore/webaudio/AudioBasicProcessorNode.h delete mode 100644 WebCore/webaudio/AudioBuffer.cpp delete mode 100644 WebCore/webaudio/AudioBuffer.h delete mode 100644 WebCore/webaudio/AudioBuffer.idl delete mode 100644 WebCore/webaudio/AudioBufferSourceNode.cpp delete mode 100644 WebCore/webaudio/AudioBufferSourceNode.h delete mode 100644 WebCore/webaudio/AudioBufferSourceNode.idl delete mode 100644 WebCore/webaudio/AudioChannelMerger.cpp delete mode 100644 WebCore/webaudio/AudioChannelMerger.h delete mode 100644 WebCore/webaudio/AudioChannelMerger.idl delete mode 100644 WebCore/webaudio/AudioChannelSplitter.cpp delete mode 100644 WebCore/webaudio/AudioChannelSplitter.h delete mode 100644 WebCore/webaudio/AudioChannelSplitter.idl delete mode 100644 WebCore/webaudio/AudioContext.cpp delete mode 100644 WebCore/webaudio/AudioContext.h delete mode 100644 WebCore/webaudio/AudioContext.idl delete mode 100644 WebCore/webaudio/AudioDestinationNode.cpp delete mode 100644 WebCore/webaudio/AudioDestinationNode.h delete mode 100644 WebCore/webaudio/AudioDestinationNode.idl delete mode 100644 WebCore/webaudio/AudioGain.h delete mode 100644 WebCore/webaudio/AudioGain.idl delete mode 100644 WebCore/webaudio/AudioGainNode.cpp delete mode 100644 WebCore/webaudio/AudioGainNode.h delete mode 100644 WebCore/webaudio/AudioGainNode.idl delete mode 100644 WebCore/webaudio/AudioListener.cpp delete mode 100644 WebCore/webaudio/AudioListener.h delete mode 100644 WebCore/webaudio/AudioListener.idl delete mode 100644 WebCore/webaudio/AudioNode.cpp delete mode 100644 WebCore/webaudio/AudioNode.h delete mode 100644 WebCore/webaudio/AudioNode.idl delete mode 100644 WebCore/webaudio/AudioNodeInput.cpp delete mode 100644 WebCore/webaudio/AudioNodeInput.h delete mode 100644 WebCore/webaudio/AudioNodeOutput.cpp delete mode 100644 WebCore/webaudio/AudioNodeOutput.h delete mode 100644 WebCore/webaudio/AudioPannerNode.cpp delete mode 100644 WebCore/webaudio/AudioPannerNode.h delete mode 100644 WebCore/webaudio/AudioPannerNode.idl delete mode 100644 WebCore/webaudio/AudioParam.cpp delete mode 100644 WebCore/webaudio/AudioParam.h delete mode 100644 WebCore/webaudio/AudioParam.idl delete mode 100644 WebCore/webaudio/AudioProcessingEvent.cpp delete mode 100644 WebCore/webaudio/AudioProcessingEvent.h delete mode 100644 WebCore/webaudio/AudioProcessingEvent.idl delete mode 100644 WebCore/webaudio/AudioSourceNode.h delete mode 100644 WebCore/webaudio/AudioSourceNode.idl delete mode 100644 WebCore/webaudio/BiquadDSPKernel.cpp delete mode 100644 WebCore/webaudio/BiquadDSPKernel.h delete mode 100644 WebCore/webaudio/BiquadProcessor.cpp delete mode 100644 WebCore/webaudio/BiquadProcessor.h delete mode 100644 WebCore/webaudio/ConvolverNode.cpp delete mode 100644 WebCore/webaudio/ConvolverNode.h delete mode 100644 WebCore/webaudio/ConvolverNode.idl delete mode 100644 WebCore/webaudio/DelayDSPKernel.cpp delete mode 100644 WebCore/webaudio/DelayDSPKernel.h delete mode 100644 WebCore/webaudio/DelayNode.cpp delete mode 100644 WebCore/webaudio/DelayNode.h delete mode 100644 WebCore/webaudio/DelayNode.idl delete mode 100644 WebCore/webaudio/DelayProcessor.cpp delete mode 100644 WebCore/webaudio/DelayProcessor.h delete mode 100644 WebCore/webaudio/HighPass2FilterNode.cpp delete mode 100644 WebCore/webaudio/HighPass2FilterNode.h delete mode 100644 WebCore/webaudio/HighPass2FilterNode.idl delete mode 100644 WebCore/webaudio/JavaScriptAudioNode.cpp delete mode 100644 WebCore/webaudio/JavaScriptAudioNode.h delete mode 100644 WebCore/webaudio/JavaScriptAudioNode.idl delete mode 100644 WebCore/webaudio/LowPass2FilterNode.cpp delete mode 100644 WebCore/webaudio/LowPass2FilterNode.h delete mode 100644 WebCore/webaudio/LowPass2FilterNode.idl delete mode 100644 WebCore/webaudio/RealtimeAnalyser.cpp delete mode 100644 WebCore/webaudio/RealtimeAnalyser.h delete mode 100644 WebCore/webaudio/RealtimeAnalyserNode.cpp delete mode 100644 WebCore/webaudio/RealtimeAnalyserNode.h delete mode 100644 WebCore/webaudio/RealtimeAnalyserNode.idl (limited to 'WebCore/webaudio') diff --git a/WebCore/webaudio/AudioBasicProcessorNode.cpp b/WebCore/webaudio/AudioBasicProcessorNode.cpp deleted file mode 100644 index 828062e..0000000 --- a/WebCore/webaudio/AudioBasicProcessorNode.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioBasicProcessorNode.h" - -#include "AudioBus.h" -#include "AudioContext.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" -#include "AudioProcessor.h" - -namespace WebCore { - -AudioBasicProcessorNode::AudioBasicProcessorNode(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) -{ - addInput(adoptPtr(new AudioNodeInput(this))); - addOutput(adoptPtr(new AudioNodeOutput(this, 0))); - - // The subclass must create m_processor. -} - -void AudioBasicProcessorNode::initialize() -{ - if (isInitialized()) - return; - - ASSERT(processor()); - processor()->initialize(); - - AudioNode::initialize(); -} - -void AudioBasicProcessorNode::uninitialize() -{ - if (!isInitialized()) - return; - - ASSERT(processor()); - processor()->uninitialize(); - - AudioNode::uninitialize(); -} - -void AudioBasicProcessorNode::process(size_t framesToProcess) -{ - AudioBus* destinationBus = output(0)->bus(); - - // The realtime thread can't block on this lock, so we call tryLock() instead. - if (m_processLock.tryLock()) { - if (!isInitialized() || !processor()) - destinationBus->zero(); - else { - AudioBus* sourceBus = input(0)->bus(); - - // FIXME: if we take "tail time" into account, then we can avoid calling processor()->process() once the tail dies down. - if (!input(0)->isConnected()) - sourceBus->zero(); - - processor()->process(sourceBus, destinationBus, framesToProcess); - } - - m_processLock.unlock(); - } else { - // Too bad - the tryLock() failed. We must be in the middle of re-connecting and were already outputting silence anyway... - destinationBus->zero(); - } -} - -// Nice optimization in the very common case allowing for "in-place" processing -void AudioBasicProcessorNode::pullInputs(size_t framesToProcess) -{ - // Render input stream - suggest to the input to render directly into output bus for in-place processing in process() if possible. - input(0)->pull(output(0)->bus(), framesToProcess); -} - -void AudioBasicProcessorNode::reset() -{ - if (processor()) - processor()->reset(); -} - -// As soon as we know the channel count of our input, we can lazily initialize. -// Sometimes this may be called more than once with different channel counts, in which case we must safely -// uninitialize and then re-initialize with the new channel count. -void AudioBasicProcessorNode::checkNumberOfChannelsForInput(AudioNodeInput* input) -{ - ASSERT(context()->isAudioThread() && context()->isGraphOwner()); - - ASSERT(input == this->input(0)); - if (input != this->input(0)) - return; - - ASSERT(processor()); - if (!processor()) - return; - - unsigned numberOfChannels = input->numberOfChannels(); - - if (isInitialized() && numberOfChannels != output(0)->numberOfChannels()) { - // We're already initialized but the channel count has changed. - // We need to be careful since we may be actively processing right now, so synchronize with process(). - MutexLocker locker(m_processLock); - uninitialize(); - } - - if (!isInitialized()) { - // This will propagate the channel count to any nodes connected further down the chain... - output(0)->setNumberOfChannels(numberOfChannels); - - // Re-initialize the processor with the new channel count. - processor()->setNumberOfChannels(numberOfChannels); - initialize(); - } -} - -unsigned AudioBasicProcessorNode::numberOfChannels() -{ - return output(0)->numberOfChannels(); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioBasicProcessorNode.h b/WebCore/webaudio/AudioBasicProcessorNode.h deleted file mode 100644 index 38bfd3b..0000000 --- a/WebCore/webaudio/AudioBasicProcessorNode.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioBasicProcessorNode_h -#define AudioBasicProcessorNode_h - -#include "AudioNode.h" -#include -#include -#include - -namespace WebCore { - -class AudioBus; -class AudioNodeInput; -class AudioProcessor; - -// AudioBasicProcessorNode is an AudioNode with one input and one output where the input and output have the same number of channels. -class AudioBasicProcessorNode : public AudioNode { -public: - AudioBasicProcessorNode(AudioContext*, double sampleRate); - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void pullInputs(size_t framesToProcess); - virtual void reset(); - virtual void initialize(); - virtual void uninitialize(); - - // Called in the main thread when the number of channels for the input may have changed. - virtual void checkNumberOfChannelsForInput(AudioNodeInput*); - - // Returns the number of channels for both the input and the output. - unsigned numberOfChannels(); - -protected: - AudioProcessor* processor() { return m_processor.get(); } - OwnPtr m_processor; - -private: - // This synchronizes live channel count changes which require an uninitialization / re-initialization. - mutable Mutex m_processLock; -}; - -} // namespace WebCore - -#endif // AudioBasicProcessorNode_h diff --git a/WebCore/webaudio/AudioBuffer.cpp b/WebCore/webaudio/AudioBuffer.cpp deleted file mode 100644 index f46d153..0000000 --- a/WebCore/webaudio/AudioBuffer.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#include "config.h" - -#if ENABLE(WEB_AUDIO) & ENABLE(3D_CANVAS) - -#include "AudioBuffer.h" - -#include "AudioBus.h" -#include "AudioFileReader.h" -#include "ExceptionCode.h" -#include - -namespace WebCore { - -PassRefPtr AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate) -{ - return adoptRef(new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate)); -} - -PassRefPtr AudioBuffer::createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, double sampleRate) -{ - OwnPtr bus = createBusFromInMemoryAudioFile(data, dataSize, mixToMono, sampleRate); - if (bus.get()) - return adoptRef(new AudioBuffer(bus.get())); - - return 0; -} - -AudioBuffer::AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate) - : m_gain(1.0) - , m_sampleRate(sampleRate) - , m_length(numberOfFrames) -{ - m_channels.reserveCapacity(numberOfChannels); - - for (unsigned i = 0; i < numberOfChannels; ++i) { - RefPtr channelDataArray = Float32Array::create(m_length); - m_channels.append(channelDataArray); - } -} - -AudioBuffer::AudioBuffer(AudioBus* bus) - : m_gain(1.0) - , m_sampleRate(bus->sampleRate()) - , m_length(bus->length()) -{ - // Copy audio data from the bus to the Float32Arrays we manage. - unsigned numberOfChannels = bus->numberOfChannels(); - m_channels.reserveCapacity(numberOfChannels); - for (unsigned i = 0; i < numberOfChannels; ++i) { - RefPtr channelDataArray = Float32Array::create(m_length); - ExceptionCode ec; - channelDataArray->setRange(bus->channel(i)->data(), m_length, 0, ec); - m_channels.append(channelDataArray); - } -} - -void AudioBuffer::releaseMemory() -{ - m_channels.clear(); -} - -Float32Array* AudioBuffer::getChannelData(unsigned channelIndex) -{ - if (channelIndex >= m_channels.size()) - return 0; - - return m_channels[channelIndex].get(); -} - -void AudioBuffer::zero() -{ - for (unsigned i = 0; i < m_channels.size(); ++i) { - if (getChannelData(i)) { - ExceptionCode ec; - getChannelData(i)->zeroRange(0, length(), ec); - } - } -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) & ENABLE(3D_CANVAS) diff --git a/WebCore/webaudio/AudioBuffer.h b/WebCore/webaudio/AudioBuffer.h deleted file mode 100644 index b11a20e..0000000 --- a/WebCore/webaudio/AudioBuffer.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2010 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 AudioBuffer_h -#define AudioBuffer_h - -#include "Float32Array.h" -#include -#include -#include -#include - -namespace WebCore { - -class AudioBus; - -class AudioBuffer : public RefCounted { -public: - static PassRefPtr create(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate); - - // Returns 0 if data is not a valid audio file. - static PassRefPtr createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, double sampleRate); - - // Format - size_t length() const { return m_length; } - double duration() const { return length() / sampleRate(); } - double sampleRate() const { return m_sampleRate; } - - // Channel data access - unsigned numberOfChannels() const { return m_channels.size(); } - Float32Array* getChannelData(unsigned channelIndex); - void zero(); - - // Scalar gain - double gain() const { return m_gain; } - void setGain(double gain) { m_gain = gain; } - - // Because an AudioBuffer has a JavaScript wrapper, which will be garbage collected, it may take awhile for this object to be deleted. - // releaseMemory() can be called when the AudioContext goes away, so we can release the memory earlier than when the garbage collection happens. - // Careful! Only call this when the page unloads, after the AudioContext is no longer processing. - void releaseMemory(); - -protected: - AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate); - AudioBuffer(AudioBus* bus); - - double m_gain; // scalar gain - double m_sampleRate; - size_t m_length; - - Vector > m_channels; -}; - -} // namespace WebCore - -#endif // AudioBuffer_h diff --git a/WebCore/webaudio/AudioBuffer.idl b/WebCore/webaudio/AudioBuffer.idl deleted file mode 100644 index e7353bf..0000000 --- a/WebCore/webaudio/AudioBuffer.idl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO & 3D_CANVAS - ] AudioBuffer { - readonly attribute long length; // in sample-frames - readonly attribute float duration; // in seconds - readonly attribute float sampleRate; // in sample-frames per second - - attribute float gain; // linear gain (default 1.0) - - // Channel access - readonly attribute unsigned long numberOfChannels; - Float32Array getChannelData(in unsigned long channelIndex); - }; -} diff --git a/WebCore/webaudio/AudioBufferSourceNode.cpp b/WebCore/webaudio/AudioBufferSourceNode.cpp deleted file mode 100644 index 05abed8..0000000 --- a/WebCore/webaudio/AudioBufferSourceNode.cpp +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioBufferSourceNode.h" - -#include "AudioContext.h" -#include "AudioNodeOutput.h" -#include -#include - -using namespace std; - -namespace WebCore { - -const double DefaultGrainDuration = 0.020; // 20ms - -PassRefPtr AudioBufferSourceNode::create(AudioContext* context, double sampleRate) -{ - return adoptRef(new AudioBufferSourceNode(context, sampleRate)); -} - -AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* context, double sampleRate) - : AudioSourceNode(context, sampleRate) - , m_buffer(0) - , m_isPlaying(false) - , m_isLooping(false) - , m_hasFinished(false) - , m_startTime(0.0) - , m_schedulingFrameDelay(0) - , m_readIndex(0) - , m_isGrain(false) - , m_grainOffset(0.0) - , m_grainDuration(DefaultGrainDuration) - , m_grainFrameCount(0) - , m_lastGain(1.0) - , m_pannerNode(0) -{ - setType(NodeTypeAudioBufferSource); - - m_gain = AudioGain::create("gain", 1.0, 0.0, 1.0); - m_playbackRate = AudioParam::create("playbackRate", 1.0, 0.0, AudioResampler::MaxRate); - - // Default to mono. A call to setBuffer() will set the number of output channels to that of the buffer. - addOutput(adoptPtr(new AudioNodeOutput(this, 1))); - - initialize(); -} - -AudioBufferSourceNode::~AudioBufferSourceNode() -{ - uninitialize(); -} - -void AudioBufferSourceNode::process(size_t framesToProcess) -{ - AudioBus* outputBus = output(0)->bus(); - - if (!isInitialized()) { - outputBus->zero(); - return; - } - - // The audio thread can't block on this lock, so we call tryLock() instead. - // Careful - this is a tryLock() and not an autolocker, so we must unlock() before every return. - if (m_processLock.tryLock()) { - // Check if it's time to start playing. - double sampleRate = this->sampleRate(); - double pitchRate = totalPitchRate(); - double quantumStartTime = context()->currentTime(); - double quantumEndTime = quantumStartTime + framesToProcess / sampleRate; - - if (!m_isPlaying || m_hasFinished || !buffer() || m_startTime >= quantumEndTime) { - // FIXME: can optimize here by propagating silent hint instead of forcing the whole chain to process silence. - outputBus->zero(); - m_processLock.unlock(); - return; - } - - // Handle sample-accurate scheduling so that buffer playback will happen at a very precise time. - m_schedulingFrameDelay = 0; - if (m_startTime >= quantumStartTime) { - // m_schedulingFrameDelay is set here only the very first render quantum (because of above check: m_startTime >= quantumEndTime) - // So: quantumStartTime <= m_startTime < quantumEndTime - ASSERT(m_startTime < quantumEndTime); - - double startTimeInQuantum = m_startTime - quantumStartTime; - double startFrameInQuantum = startTimeInQuantum * sampleRate; - - // m_schedulingFrameDelay is used in provideInput(), so factor in the current playback pitch rate. - m_schedulingFrameDelay = static_cast(pitchRate * startFrameInQuantum); - } - - // FIXME: optimization opportunity: - // With a bit of work, it should be possible to avoid going through the resampler completely when the pitchRate == 1, - // especially if the pitchRate has never deviated from 1 in the past. - - // Read the samples through the pitch resampler. Our provideInput() method will be called by the resampler. - m_resampler.setRate(pitchRate); - m_resampler.process(this, outputBus, framesToProcess); - - // Apply the gain (in-place) to the output bus. - double totalGain = gain()->value() * m_buffer->gain(); - outputBus->copyWithGainFrom(*outputBus, &m_lastGain, totalGain); - - m_processLock.unlock(); - } else { - // Too bad - the tryLock() failed. We must be in the middle of changing buffers and were already outputting silence anyway. - outputBus->zero(); - } -} - -// The resampler calls us back here to get the input samples from our buffer. -void AudioBufferSourceNode::provideInput(AudioBus* bus, size_t numberOfFrames) -{ - ASSERT(context()->isAudioThread()); - - // Basic sanity checking - ASSERT(bus); - ASSERT(buffer()); - if (!bus || !buffer()) - return; - - unsigned numberOfChannels = this->numberOfChannels(); - unsigned busNumberOfChannels = bus->numberOfChannels(); - - // FIXME: we can add support for sources with more than two channels, but this is not a common case. - bool channelCountGood = numberOfChannels == busNumberOfChannels && (numberOfChannels == 1 || numberOfChannels == 2); - ASSERT(channelCountGood); - if (!channelCountGood) - return; - - // Get the destination pointers. - float* destinationL = bus->channel(0)->data(); - ASSERT(destinationL); - if (!destinationL) - return; - float* destinationR = (numberOfChannels < 2) ? 0 : bus->channel(1)->data(); - - size_t bufferLength = buffer()->length(); - double bufferSampleRate = buffer()->sampleRate(); - - // Calculate the start and end frames in our buffer that we want to play. - // If m_isGrain is true, then we will be playing a portion of the total buffer. - unsigned startFrame = m_isGrain ? static_cast(m_grainOffset * bufferSampleRate) : 0; - unsigned endFrame = m_isGrain ? static_cast(startFrame + m_grainDuration * bufferSampleRate) : bufferLength; - - // This is a HACK to allow for HRTF tail-time - avoids glitch at end. - // FIXME: implement tailTime for each AudioNode for a more general solution to this problem. - if (m_isGrain) - endFrame += 512; - - // Do some sanity checking. - if (startFrame >= bufferLength) - startFrame = !bufferLength ? 0 : bufferLength - 1; - if (endFrame > bufferLength) - endFrame = bufferLength; - if (m_readIndex >= endFrame) - m_readIndex = startFrame; // reset to start - - int framesToProcess = numberOfFrames; - - // Handle sample-accurate scheduling so that we play the buffer at a very precise time. - // m_schedulingFrameDelay will only be non-zero the very first time that provideInput() is called, which corresponds - // with the very start of the buffer playback. - if (m_schedulingFrameDelay > 0) { - ASSERT(m_schedulingFrameDelay <= framesToProcess); - if (m_schedulingFrameDelay <= framesToProcess) { - // Generate silence for the initial portion of the destination. - memset(destinationL, 0, sizeof(float) * m_schedulingFrameDelay); - destinationL += m_schedulingFrameDelay; - if (destinationR) { - memset(destinationR, 0, sizeof(float) * m_schedulingFrameDelay); - destinationR += m_schedulingFrameDelay; - } - - // Since we just generated silence for the initial portion, we have fewer frames to provide. - framesToProcess -= m_schedulingFrameDelay; - } - } - - // We have to generate a certain number of output sample-frames, but we need to handle the case where we wrap around - // from the end of the buffer to the start if playing back with looping and also the case where we simply reach the - // end of the sample data, but haven't yet rendered numberOfFrames worth of output. - while (framesToProcess > 0) { - ASSERT(m_readIndex <= endFrame); - if (m_readIndex > endFrame) - return; - - // Figure out how many frames we can process this time. - int framesAvailable = endFrame - m_readIndex; - int framesThisTime = min(framesToProcess, framesAvailable); - - // Create the destination bus for the part of the destination we're processing this time. - AudioBus currentDestinationBus(busNumberOfChannels, framesThisTime, false); - currentDestinationBus.setChannelMemory(0, destinationL, framesThisTime); - if (busNumberOfChannels > 1) - currentDestinationBus.setChannelMemory(1, destinationR, framesThisTime); - - // Generate output from the buffer. - readFromBuffer(¤tDestinationBus, framesThisTime); - - // Update the destination pointers. - destinationL += framesThisTime; - if (busNumberOfChannels > 1) - destinationR += framesThisTime; - - framesToProcess -= framesThisTime; - - // Handle the case where we reach the end of the part of the sample data we're supposed to play for the buffer. - if (m_readIndex >= endFrame) { - m_readIndex = startFrame; - m_grainFrameCount = 0; - - if (!looping()) { - // If we're not looping, then stop playing when we get to the end. - m_isPlaying = false; - - if (framesToProcess > 0) { - // We're not looping and we've reached the end of the sample data, but we still need to provide more output, - // so generate silence for the remaining. - memset(destinationL, 0, sizeof(float) * framesToProcess); - - if (destinationR) - memset(destinationR, 0, sizeof(float) * framesToProcess); - } - - if (!m_hasFinished) { - // Let the context dereference this AudioNode. - context()->notifyNodeFinishedProcessing(this); - m_hasFinished = true; - } - return; - } - } - } -} - -void AudioBufferSourceNode::readFromBuffer(AudioBus* destinationBus, size_t framesToProcess) -{ - bool isBusGood = destinationBus && destinationBus->length() == framesToProcess && destinationBus->numberOfChannels() == numberOfChannels(); - ASSERT(isBusGood); - if (!isBusGood) - return; - - unsigned numberOfChannels = this->numberOfChannels(); - // FIXME: we can add support for sources with more than two channels, but this is not a common case. - bool channelCountGood = numberOfChannels == 1 || numberOfChannels == 2; - ASSERT(channelCountGood); - if (!channelCountGood) - return; - - // Get pointers to the start of the sample buffer. - float* sourceL = m_buffer->getChannelData(0)->data(); - float* sourceR = m_buffer->numberOfChannels() == 2 ? m_buffer->getChannelData(1)->data() : 0; - - // Sanity check buffer access. - bool isSourceGood = sourceL && (numberOfChannels == 1 || sourceR) && m_readIndex + framesToProcess <= m_buffer->length(); - ASSERT(isSourceGood); - if (!isSourceGood) - return; - - // Offset the pointers to the current read position in the sample buffer. - sourceL += m_readIndex; - sourceR += m_readIndex; - - // Get pointers to the destination. - float* destinationL = destinationBus->channel(0)->data(); - float* destinationR = numberOfChannels == 2 ? destinationBus->channel(1)->data() : 0; - bool isDestinationGood = destinationL && (numberOfChannels == 1 || destinationR); - ASSERT(isDestinationGood); - if (!isDestinationGood) - return; - - if (m_isGrain) - readFromBufferWithGrainEnvelope(sourceL, sourceR, destinationL, destinationR, framesToProcess); - else { - // Simply copy the data from the source buffer to the destination. - memcpy(destinationL, sourceL, sizeof(float) * framesToProcess); - if (numberOfChannels == 2) - memcpy(destinationR, sourceR, sizeof(float) * framesToProcess); - } - - // Advance the buffer's read index. - m_readIndex += framesToProcess; -} - -void AudioBufferSourceNode::readFromBufferWithGrainEnvelope(float* sourceL, float* sourceR, float* destinationL, float* destinationR, size_t framesToProcess) -{ - ASSERT(sourceL && destinationL); - if (!sourceL || !destinationL) - return; - - int grainFrameLength = static_cast(m_grainDuration * m_buffer->sampleRate()); - bool isStereo = sourceR && destinationR; - - int n = framesToProcess; - while (n--) { - // Apply the grain envelope. - float x = static_cast(m_grainFrameCount) / static_cast(grainFrameLength); - m_grainFrameCount++; - - x = min(1.0f, x); - float grainEnvelope = sinf(piFloat * x); - - *destinationL++ = grainEnvelope * *sourceL++; - - if (isStereo) - *destinationR++ = grainEnvelope * *sourceR++; - } -} - -void AudioBufferSourceNode::reset() -{ - m_resampler.reset(); - m_readIndex = 0; - m_grainFrameCount = 0; - m_lastGain = gain()->value(); -} - -void AudioBufferSourceNode::setBuffer(AudioBuffer* buffer) -{ - ASSERT(isMainThread()); - - // The context must be locked since changing the buffer can re-configure the number of channels that are output. - AudioContext::AutoLocker contextLocker(context()); - - // This synchronizes with process(). - MutexLocker processLocker(m_processLock); - - if (buffer) { - // Do any necesssary re-configuration to the buffer's number of channels. - unsigned numberOfChannels = buffer->numberOfChannels(); - m_resampler.configureChannels(numberOfChannels); - output(0)->setNumberOfChannels(numberOfChannels); - } - - m_readIndex = 0; - m_buffer = buffer; -} - -unsigned AudioBufferSourceNode::numberOfChannels() -{ - return output(0)->numberOfChannels(); -} - -void AudioBufferSourceNode::noteOn(double when) -{ - ASSERT(isMainThread()); - if (m_isPlaying) - return; - - m_isGrain = false; - m_startTime = when; - m_readIndex = 0; - m_isPlaying = true; -} - -void AudioBufferSourceNode::noteGrainOn(double when, double grainOffset, double grainDuration) -{ - ASSERT(isMainThread()); - if (m_isPlaying) - return; - - if (!buffer()) - return; - - // Do sanity checking of grain parameters versus buffer size. - double bufferDuration = buffer()->duration(); - - if (grainDuration > bufferDuration) - return; // FIXME: maybe should throw exception - consider in specification. - - double maxGrainOffset = bufferDuration - grainDuration; - maxGrainOffset = max(0.0, maxGrainOffset); - - grainOffset = max(0.0, grainOffset); - grainOffset = min(maxGrainOffset, grainOffset); - m_grainOffset = grainOffset; - - m_grainDuration = grainDuration; - m_grainFrameCount = 0; - - m_isGrain = true; - m_startTime = when; - m_readIndex = static_cast(m_grainOffset * buffer()->sampleRate()); - m_isPlaying = true; -} - -void AudioBufferSourceNode::noteOff(double) -{ - ASSERT(isMainThread()); - if (!m_isPlaying) - return; - - // FIXME: the "when" argument to this method is ignored. - m_isPlaying = false; - m_readIndex = 0; -} - -double AudioBufferSourceNode::totalPitchRate() -{ - double dopplerRate = 1.0; - if (m_pannerNode.get()) - dopplerRate = m_pannerNode->dopplerRate(); - - // Incorporate buffer's sample-rate versus AudioContext's sample-rate. - // Normally it's not an issue because buffers are loaded at the AudioContext's sample-rate, but we can handle it in any case. - double sampleRateFactor = 1.0; - if (buffer()) - sampleRateFactor = buffer()->sampleRate() / sampleRate(); - - double basePitchRate = playbackRate()->value(); - - double totalRate = dopplerRate * sampleRateFactor * basePitchRate; - - // Sanity check the total rate. It's very important that the resampler not get any bad rate values. - totalRate = max(0.0, totalRate); - totalRate = min(AudioResampler::MaxRate, totalRate); - - bool isTotalRateValid = !isnan(totalRate) && !isinf(totalRate); - ASSERT(isTotalRateValid); - if (!isTotalRateValid) - totalRate = 1.0; - - return totalRate; -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioBufferSourceNode.h b/WebCore/webaudio/AudioBufferSourceNode.h deleted file mode 100644 index 40b8555..0000000 --- a/WebCore/webaudio/AudioBufferSourceNode.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioBufferSourceNode_h -#define AudioBufferSourceNode_h - -#include "AudioBuffer.h" -#include "AudioBus.h" -#include "AudioGain.h" -#include "AudioPannerNode.h" -#include "AudioResampler.h" -#include "AudioSourceNode.h" -#include "AudioSourceProvider.h" -#include -#include -#include - -namespace WebCore { - -class AudioContext; - -// 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 AudioSourceProvider { -public: - static PassRefPtr create(AudioContext*, double sampleRate); - - virtual ~AudioBufferSourceNode(); - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void reset(); - - // AudioSourceProvider - // When process() is called, the resampler calls provideInput (in the audio thread) to gets its input stream. - virtual void provideInput(AudioBus*, size_t numberOfFrames); - - // setBuffer() is called on the main thread. This is the buffer we use for playback. - void setBuffer(AudioBuffer*); - AudioBuffer* buffer() { return m_buffer.get(); } - - // numberOfChannels() returns the number of output channels. This value equals the number of channels from the buffer. - // If a new buffer is set with a different number of channels, then this value will dynamically change. - unsigned numberOfChannels(); - - // 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); - - bool looping() const { return m_isLooping; } - void setLooping(bool looping) { m_isLooping = looping; } - - AudioGain* gain() { return m_gain.get(); } - AudioParam* playbackRate() { return m_playbackRate.get(); } - - // If a panner node is set, then we can incorporate doppler shift into the playback pitch rate. - void setPannerNode(PassRefPtr pannerNode) { m_pannerNode = pannerNode; } - -private: - AudioBufferSourceNode(AudioContext*, double sampleRate); - - // m_buffer holds the sample data which this node outputs. - RefPtr m_buffer; - - // Used for the "gain" and "playbackRate" attributes. - RefPtr m_gain; - RefPtr m_playbackRate; - - // m_isPlaying is set to true when noteOn() or noteGrainOn() is called. - bool m_isPlaying; - - // If m_isLooping is false, then this node will be done playing and become inactive after it reaches the end of the sample data in the buffer. - // If true, it will wrap around to the start of the buffer each time it reaches the end. - bool m_isLooping; - - // This node is considered finished when it reaches the end of the buffer's sample data after noteOn() has been called. - // This will only be set to true if m_isLooping == false. - bool m_hasFinished; - - // 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_schedulingFrameDelay is the sample-accurate scheduling offset. - // It's used so that we start rendering audio samples at a very precise point in time. - // It will only be a non-zero value the very first render quantum that we render from the buffer. - int m_schedulingFrameDelay; - - // m_readIndex is a sample-frame index into our buffer representing the current playback position. - unsigned m_readIndex; - - // Granular playback - bool m_isGrain; - double m_grainOffset; // in seconds - double m_grainDuration; // in seconds - int m_grainFrameCount; // keeps track of which frame in the grain we're currently rendering - - // totalPitchRate() returns the instantaneous pitch rate (non-time preserving). - // It incorporates the base pitch rate, any sample-rate conversion factor from the buffer, and any doppler shift from an associated panner node. - double totalPitchRate(); - - // m_resampler performs the pitch rate changes to the buffer playback. - AudioResampler m_resampler; - - // m_lastGain provides continuity when we dynamically adjust the gain. - double m_lastGain; - - // We optionally keep track of a panner node which has a doppler shift that is incorporated into the pitch rate. - RefPtr m_pannerNode; - - // This synchronizes process() with setBuffer() which can cause dynamic channel count changes. - mutable Mutex m_processLock; - - // Reads the next framesToProcess sample-frames from the AudioBuffer into destinationBus. - // A grain envelope will be applied if m_isGrain is set to true. - void readFromBuffer(AudioBus* destinationBus, size_t framesToProcess); - - // readFromBufferWithGrainEnvelope() is a low-level blitter which reads from the AudioBuffer and applies a grain envelope. - void readFromBufferWithGrainEnvelope(float* sourceL, float* sourceR, float* destinationL, float* destinationR, size_t framesToProcess); -}; - -} // namespace WebCore - -#endif // AudioBufferSourceNode_h diff --git a/WebCore/webaudio/AudioBufferSourceNode.idl b/WebCore/webaudio/AudioBufferSourceNode.idl deleted file mode 100644 index dec7461..0000000 --- a/WebCore/webaudio/AudioBufferSourceNode.idl +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - // A cached (non-streamed), memory-resident audio source - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] AudioBufferSourceNode : AudioSourceNode { - attribute [JSCCustomSetter] AudioBuffer buffer; - - readonly attribute AudioGain gain; - readonly attribute AudioParam playbackRate; - attribute boolean looping; // FIXME: change name to 'loop' once samples are updated - - void noteOn(in float when); - void noteGrainOn(in float when, in float grainOffset, in float grainDuration); - void noteOff(in float when); - }; -} diff --git a/WebCore/webaudio/AudioChannelMerger.cpp b/WebCore/webaudio/AudioChannelMerger.cpp deleted file mode 100644 index c418a61..0000000 --- a/WebCore/webaudio/AudioChannelMerger.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#include "config.h" - -#if ENABLE(WEB_AUDIO) - -#include "AudioChannelMerger.h" - -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" - -namespace WebCore { - -// This is considering that 5.1 (6 channels) is the largest we'll ever deal with. -// It can easily be increased to support more if the web audio specification is updated. -const unsigned NumberOfInputs = 6; - -AudioChannelMerger::AudioChannelMerger(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) -{ - // Create a fixed number of inputs (able to handle the maximum number of channels we deal with). - for (unsigned i = 0; i < NumberOfInputs; ++i) - addInput(adoptPtr(new AudioNodeInput(this))); - - addOutput(adoptPtr(new AudioNodeOutput(this, 1))); - - setType(NodeTypeChannelMerger); - - initialize(); -} - -void AudioChannelMerger::process(size_t framesToProcess) -{ - AudioNodeOutput* output = this->output(0); - ASSERT(output); - ASSERT_UNUSED(framesToProcess, framesToProcess == output->bus()->length()); - - // Count how many channels we have all together from all of the inputs. - unsigned numberOfOutputChannels = 0; - for (unsigned i = 0; i < numberOfInputs(); ++i) { - AudioNodeInput* input = this->input(i); - if (input->isConnected()) - numberOfOutputChannels += input->bus()->numberOfChannels(); - } - - // Set the correct number of channels on the output - output->setNumberOfChannels(numberOfOutputChannels); - - // Now merge the channels back into one output. - unsigned outputChannelIndex = 0; - for (unsigned i = 0; i < numberOfInputs(); ++i) { - AudioNodeInput* input = this->input(i); - if (input->isConnected()) { - unsigned numberOfInputChannels = input->bus()->numberOfChannels(); - - // Merge channels from this particular input. - for (unsigned j = 0; j < numberOfInputChannels; ++j) { - AudioChannel* inputChannel = input->bus()->channel(j); - AudioChannel* outputChannel = output->bus()->channel(outputChannelIndex); - outputChannel->copyFrom(inputChannel); - - ++outputChannelIndex; - } - } - } - - ASSERT(outputChannelIndex == numberOfOutputChannels); -} - -void AudioChannelMerger::reset() -{ -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioChannelMerger.h b/WebCore/webaudio/AudioChannelMerger.h deleted file mode 100644 index 20a9628..0000000 --- a/WebCore/webaudio/AudioChannelMerger.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010 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 AudioChannelMerger_h -#define AudioChannelMerger_h - -#include "AudioNode.h" -#include - -namespace WebCore { - -class AudioContext; - -class AudioChannelMerger : public AudioNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new AudioChannelMerger(context, sampleRate)); - } - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void reset(); - -private: - AudioChannelMerger(AudioContext*, double sampleRate); -}; - -} // namespace WebCore - -#endif // AudioChannelMerger_h diff --git a/WebCore/webaudio/AudioChannelMerger.idl b/WebCore/webaudio/AudioChannelMerger.idl deleted file mode 100644 index 3862af9..0000000 --- a/WebCore/webaudio/AudioChannelMerger.idl +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO - ] AudioChannelMerger : AudioNode { - }; -} diff --git a/WebCore/webaudio/AudioChannelSplitter.cpp b/WebCore/webaudio/AudioChannelSplitter.cpp deleted file mode 100644 index f4fa041..0000000 --- a/WebCore/webaudio/AudioChannelSplitter.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioChannelSplitter.h" - -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" - -namespace WebCore { - -// This is considering that 5.1 (6 channels) is the largest we'll ever deal with. -// It can easily be increased to support more if the web audio specification is updated. -const unsigned NumberOfOutputs = 6; - -AudioChannelSplitter::AudioChannelSplitter(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) -{ - addInput(adoptPtr(new AudioNodeInput(this))); - - // Create a fixed number of outputs (able to handle the maximum number of channels fed to an input). - for (unsigned i = 0; i < NumberOfOutputs; ++i) - addOutput(adoptPtr(new AudioNodeOutput(this, 1))); - - setType(NodeTypeChannelSplitter); - - initialize(); -} - -void AudioChannelSplitter::process(size_t framesToProcess) -{ - AudioBus* source = input(0)->bus(); - ASSERT(source); - ASSERT_UNUSED(framesToProcess, framesToProcess == source->length()); - - unsigned numberOfSourceChannels = source->numberOfChannels(); - - ASSERT(numberOfOutputs() == NumberOfOutputs); - for (unsigned i = 0; i < NumberOfOutputs; ++i) { - AudioBus* destination = output(i)->bus(); - ASSERT(destination); - - if (i < numberOfSourceChannels) { - // Split the channel out if it exists in the source. - // It would be nice to avoid the copy and simply pass along pointers, but this becomes extremely difficult with fanout and fanin. - destination->channel(0)->copyFrom(source->channel(i)); - } else if (output(i)->renderingFanOutCount() > 0) { - // Only bother zeroing out the destination if it's connected to anything - destination->zero(); - } - } -} - -void AudioChannelSplitter::reset() -{ -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioChannelSplitter.h b/WebCore/webaudio/AudioChannelSplitter.h deleted file mode 100644 index 7dadac5..0000000 --- a/WebCore/webaudio/AudioChannelSplitter.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioChannelSplitter_h -#define AudioChannelSplitter_h - -#include "AudioNode.h" -#include - -namespace WebCore { - -class AudioContext; - -class AudioChannelSplitter : public AudioNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new AudioChannelSplitter(context, sampleRate)); - } - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void reset(); - -private: - AudioChannelSplitter(AudioContext*, double sampleRate); -}; - -} // namespace WebCore - -#endif // AudioChannelSplitter_h diff --git a/WebCore/webaudio/AudioChannelSplitter.idl b/WebCore/webaudio/AudioChannelSplitter.idl deleted file mode 100644 index 076c051..0000000 --- a/WebCore/webaudio/AudioChannelSplitter.idl +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO - ] AudioChannelSplitter : AudioNode { - }; -} diff --git a/WebCore/webaudio/AudioContext.cpp b/WebCore/webaudio/AudioContext.cpp deleted file mode 100644 index a452775..0000000 --- a/WebCore/webaudio/AudioContext.cpp +++ /dev/null @@ -1,529 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioContext.h" - -#include "ArrayBuffer.h" -#include "AudioBuffer.h" -#include "AudioBufferSourceNode.h" -#include "AudioChannelMerger.h" -#include "AudioChannelSplitter.h" -#include "AudioGainNode.h" -#include "AudioListener.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" -#include "AudioPannerNode.h" -#include "ConvolverNode.h" -#include "DelayNode.h" -#include "Document.h" -#include "HRTFDatabaseLoader.h" -#include "HRTFPanner.h" -#include "HighPass2FilterNode.h" -#include "JavaScriptAudioNode.h" -#include "LowPass2FilterNode.h" -#include "PlatformString.h" -#include "RealtimeAnalyserNode.h" - -#include -#include -#include - -// FIXME: check the proper way to reference an undefined thread ID -const int UndefinedThreadIdentifier = 0xffffffff; - -const unsigned MaxNodesToDeletePerQuantum = 10; - -namespace WebCore { - -PassRefPtr AudioContext::create(Document* document) -{ - return adoptRef(new AudioContext(document)); -} - -AudioContext::AudioContext(Document* document) - : ActiveDOMObject(document, this) - , m_isInitialized(false) - , m_isAudioThreadFinished(false) - , m_document(document) - , m_destinationNode(0) - , m_connectionCount(0) - , m_audioThread(0) - , m_graphOwnerThread(UndefinedThreadIdentifier) -{ - // Note: because adoptRef() won't be called until we leave this constructor, but code in this constructor needs to reference this context, - // relax the check. - relaxAdoptionRequirement(); - - m_destinationNode = AudioDestinationNode::create(this); - m_listener = AudioListener::create(); - m_temporaryMonoBus = adoptPtr(new AudioBus(1, AudioNode::ProcessingSizeInFrames)); - m_temporaryStereoBus = adoptPtr(new AudioBus(2, AudioNode::ProcessingSizeInFrames)); - - // This sets in motion an asynchronous loading mechanism on another thread. - // We can check m_hrtfDatabaseLoader->isLoaded() to find out whether or not it has been fully loaded. - // It's not that useful to have a callback function for this since the audio thread automatically starts rendering on the graph - // when this has finished (see AudioDestinationNode). - m_hrtfDatabaseLoader = HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(sampleRate()); -} - -AudioContext::~AudioContext() -{ -#if DEBUG_AUDIONODE_REFERENCES - printf("%p: AudioContext::~AudioContext()\n", this); -#endif - // AudioNodes keep a reference to their context, so there should be no way to be in the destructor if there are still AudioNodes around. - ASSERT(!m_nodesToDelete.size()); - ASSERT(!m_referencedNodes.size()); - ASSERT(!m_finishedNodes.size()); -} - -void AudioContext::lazyInitialize() -{ - if (!m_isInitialized) { - // Don't allow the context to initialize a second time after it's already been explicitly uninitialized. - ASSERT(!m_isAudioThreadFinished); - if (!m_isAudioThreadFinished) { - if (m_destinationNode.get()) { - // This starts the audio thread. The destination node's provideInput() method will now be called repeatedly to render audio. - // Each time provideInput() is called, a portion of the audio stream is rendered. Let's call this time period a "render quantum". - m_destinationNode->initialize(); - } - m_isInitialized = true; - } - } -} - -void AudioContext::uninitialize() -{ - if (m_isInitialized) { - // This stops the audio thread and all audio rendering. - m_destinationNode->uninitialize(); - - // Don't allow the context to initialize a second time after it's already been explicitly uninitialized. - m_isAudioThreadFinished = true; - - // We have to release our reference to the destination node before the context will ever be deleted since the destination node holds a reference to the context. - m_destinationNode.clear(); - - // Get rid of the sources which may still be playing. - derefUnfinishedSourceNodes(); - - // Because the AudioBuffers are garbage collected, we can't delete them here. - // Instead, at least release the potentially large amount of allocated memory for the audio data. - // Note that we do this *after* the context is uninitialized and stops processing audio. - for (unsigned i = 0; i < m_allocatedBuffers.size(); ++i) - m_allocatedBuffers[i]->releaseMemory(); - m_allocatedBuffers.clear(); - - m_isInitialized = false; - } -} - -bool AudioContext::isInitialized() const -{ - return m_isInitialized; -} - -bool AudioContext::isRunnable() const -{ - if (!isInitialized()) - return false; - - // Check with the HRTF spatialization system to see if it's finished loading. - return m_hrtfDatabaseLoader->isLoaded(); -} - -void AudioContext::stop() -{ - m_document = 0; // document is going away - uninitialize(); -} - -Document* AudioContext::document() -{ - ASSERT(m_document); - return m_document; -} - -bool AudioContext::hasDocument() -{ - return m_document; -} - -void AudioContext::refBuffer(PassRefPtr buffer) -{ - m_allocatedBuffers.append(buffer); -} - -PassRefPtr AudioContext::createBuffer(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate) -{ - return AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate); -} - -PassRefPtr AudioContext::createBuffer(ArrayBuffer* arrayBuffer, bool mixToMono) -{ - ASSERT(arrayBuffer); - if (!arrayBuffer) - return 0; - - return AudioBuffer::createFromAudioFileData(arrayBuffer->data(), arrayBuffer->byteLength(), mixToMono, sampleRate()); -} - -PassRefPtr AudioContext::createBufferSource() -{ - ASSERT(isMainThread()); - lazyInitialize(); - RefPtr node = AudioBufferSourceNode::create(this, m_destinationNode->sampleRate()); - - refNode(node.get()); // context keeps reference until source has finished playing - return node; -} - -PassRefPtr AudioContext::createJavaScriptNode(size_t bufferSize) -{ - ASSERT(isMainThread()); - lazyInitialize(); - RefPtr node = JavaScriptAudioNode::create(this, m_destinationNode->sampleRate(), bufferSize); - - refNode(node.get()); // context keeps reference until we stop making javascript rendering callbacks - return node; -} - -PassRefPtr AudioContext::createLowPass2Filter() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return LowPass2FilterNode::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createHighPass2Filter() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return HighPass2FilterNode::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createPanner() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return AudioPannerNode::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createConvolver() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return ConvolverNode::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createAnalyser() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return RealtimeAnalyserNode::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createGainNode() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return AudioGainNode::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createDelayNode() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return DelayNode::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createChannelSplitter() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return AudioChannelSplitter::create(this, m_destinationNode->sampleRate()); -} - -PassRefPtr AudioContext::createChannelMerger() -{ - ASSERT(isMainThread()); - lazyInitialize(); - return AudioChannelMerger::create(this, m_destinationNode->sampleRate()); -} - -void AudioContext::notifyNodeFinishedProcessing(AudioNode* node) -{ - ASSERT(isAudioThread()); - m_finishedNodes.append(node); -} - -void AudioContext::derefFinishedSourceNodes() -{ - ASSERT(isGraphOwner()); - ASSERT(isAudioThread() || isAudioThreadFinished()); - for (unsigned i = 0; i < m_finishedNodes.size(); i++) - derefNode(m_finishedNodes[i]); - - m_finishedNodes.clear(); -} - -void AudioContext::refNode(AudioNode* node) -{ - ASSERT(isMainThread()); - AutoLocker locker(this); - - node->ref(AudioNode::RefTypeConnection); - m_referencedNodes.append(node); -} - -void AudioContext::derefNode(AudioNode* node) -{ - ASSERT(isGraphOwner()); - - node->deref(AudioNode::RefTypeConnection); - - for (unsigned i = 0; i < m_referencedNodes.size(); ++i) { - if (node == m_referencedNodes[i]) { - m_referencedNodes.remove(i); - break; - } - } -} - -void AudioContext::derefUnfinishedSourceNodes() -{ - ASSERT(isMainThread() && isAudioThreadFinished()); - for (unsigned i = 0; i < m_referencedNodes.size(); ++i) - m_referencedNodes[i]->deref(AudioNode::RefTypeConnection); - - m_referencedNodes.clear(); -} - -void AudioContext::lock(bool& mustReleaseLock) -{ - // Don't allow regular lock in real-time audio thread. - ASSERT(isMainThread()); - - ThreadIdentifier thisThread = currentThread(); - - if (thisThread == m_graphOwnerThread) { - // We already have the lock. - mustReleaseLock = false; - } else { - // Acquire the lock. - m_contextGraphMutex.lock(); - m_graphOwnerThread = thisThread; - mustReleaseLock = true; - } -} - -bool AudioContext::tryLock(bool& mustReleaseLock) -{ - ThreadIdentifier thisThread = currentThread(); - bool isAudioThread = thisThread == audioThread(); - - // Try to catch cases of using try lock on main thread - it should use regular lock. - ASSERT(isAudioThread || isAudioThreadFinished()); - - if (!isAudioThread) { - // In release build treat tryLock() as lock() (since above ASSERT(isAudioThread) never fires) - this is the best we can do. - lock(mustReleaseLock); - return true; - } - - bool hasLock; - - if (thisThread == m_graphOwnerThread) { - // Thread already has the lock. - hasLock = true; - mustReleaseLock = false; - } else { - // Don't already have the lock - try to acquire it. - hasLock = m_contextGraphMutex.tryLock(); - - if (hasLock) - m_graphOwnerThread = thisThread; - - mustReleaseLock = hasLock; - } - - return hasLock; -} - -void AudioContext::unlock() -{ - ASSERT(currentThread() == m_graphOwnerThread); - - m_graphOwnerThread = UndefinedThreadIdentifier; - m_contextGraphMutex.unlock(); -} - -bool AudioContext::isAudioThread() const -{ - return currentThread() == m_audioThread; -} - -bool AudioContext::isGraphOwner() const -{ - return currentThread() == m_graphOwnerThread; -} - -void AudioContext::addDeferredFinishDeref(AudioNode* node, AudioNode::RefType refType) -{ - ASSERT(isAudioThread()); - m_deferredFinishDerefList.append(AudioContext::RefInfo(node, refType)); -} - -void AudioContext::handlePreRenderTasks() -{ - ASSERT(isAudioThread()); - - // At the beginning of every render quantum, try to update the internal rendering graph state (from main thread changes). - // 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(); - handleDirtyAudioNodeOutputs(); - - if (mustReleaseLock) - unlock(); - } -} - -void AudioContext::handlePostRenderTasks() -{ - ASSERT(isAudioThread()); - - // Must use a tryLock() here too. Don't worry, the lock will very rarely be contended and this method is called frequently. - // The worst that can happen is that there will be some nodes which will take slightly longer than usual to be deleted or removed - // from the render graph (in which case they'll render silence). - bool mustReleaseLock; - if (tryLock(mustReleaseLock)) { - // Take care of finishing any derefs where the tryLock() failed previously. - handleDeferredFinishDerefs(); - - // Dynamically clean up nodes which are no longer needed. - derefFinishedSourceNodes(); - - // Finally actually delete. - deleteMarkedNodes(); - - // Fixup the state of any dirty AudioNodeInputs and AudioNodeOutputs. - handleDirtyAudioNodeInputs(); - handleDirtyAudioNodeOutputs(); - - if (mustReleaseLock) - unlock(); - } -} - -void AudioContext::handleDeferredFinishDerefs() -{ - ASSERT(isAudioThread() && isGraphOwner()); - for (unsigned i = 0; i < m_deferredFinishDerefList.size(); ++i) { - AudioNode* node = m_deferredFinishDerefList[i].m_node; - AudioNode::RefType refType = m_deferredFinishDerefList[i].m_refType; - node->finishDeref(refType); - } - - m_deferredFinishDerefList.clear(); -} - -void AudioContext::markForDeletion(AudioNode* node) -{ - ASSERT(isGraphOwner()); - m_nodesToDelete.append(node); -} - -void AudioContext::deleteMarkedNodes() -{ - ASSERT(isGraphOwner() || isAudioThreadFinished()); - - // Note: deleting an AudioNode can cause m_nodesToDelete to grow. - size_t nodesDeleted = 0; - while (size_t n = m_nodesToDelete.size()) { - AudioNode* node = m_nodesToDelete[n - 1]; - m_nodesToDelete.removeLast(); - - // Before deleting the node, clear out any AudioNodeInputs from m_dirtyAudioNodeInputs. - unsigned numberOfInputs = node->numberOfInputs(); - for (unsigned i = 0; i < numberOfInputs; ++i) - m_dirtyAudioNodeInputs.remove(node->input(i)); - - // Before deleting the node, clear out any AudioNodeOutputs from m_dirtyAudioNodeOutputs. - unsigned numberOfOutputs = node->numberOfOutputs(); - for (unsigned i = 0; i < numberOfOutputs; ++i) - m_dirtyAudioNodeOutputs.remove(node->output(i)); - - // Finally, delete it. - delete node; - - // Don't delete too many nodes per render quantum since we don't want to do too much work in the realtime audio thread. - if (++nodesDeleted > MaxNodesToDeletePerQuantum) - break; - } -} - -void AudioContext::markAudioNodeInputDirty(AudioNodeInput* input) -{ - ASSERT(isGraphOwner()); - m_dirtyAudioNodeInputs.add(input); -} - -void AudioContext::markAudioNodeOutputDirty(AudioNodeOutput* output) -{ - ASSERT(isGraphOwner()); - m_dirtyAudioNodeOutputs.add(output); -} - -void AudioContext::handleDirtyAudioNodeInputs() -{ - ASSERT(isGraphOwner()); - - for (HashSet::iterator i = m_dirtyAudioNodeInputs.begin(); i != m_dirtyAudioNodeInputs.end(); ++i) - (*i)->updateRenderingState(); - - m_dirtyAudioNodeInputs.clear(); -} - -void AudioContext::handleDirtyAudioNodeOutputs() -{ - ASSERT(isGraphOwner()); - - for (HashSet::iterator i = m_dirtyAudioNodeOutputs.begin(); i != m_dirtyAudioNodeOutputs.end(); ++i) - (*i)->updateRenderingState(); - - m_dirtyAudioNodeOutputs.clear(); -} - - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioContext.h b/WebCore/webaudio/AudioContext.h deleted file mode 100644 index ddd474c..0000000 --- a/WebCore/webaudio/AudioContext.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioContext_h -#define AudioContext_h - -#include "ActiveDOMObject.h" -#include "AudioBus.h" -#include "AudioDestinationNode.h" -#include "HRTFDatabaseLoader.h" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace WebCore { - -class ArrayBuffer; -class AudioBuffer; -class AudioBufferSourceNode; -class AudioChannelMerger; -class AudioChannelSplitter; -class AudioGainNode; -class AudioPannerNode; -class AudioListener; -class DelayNode; -class Document; -class LowPass2FilterNode; -class HighPass2FilterNode; -class ConvolverNode; -class RealtimeAnalyserNode; -class JavaScriptAudioNode; - -// AudioContext is the cornerstone of the web audio API and all AudioNodes are created from it. -// For thread safety between the audio thread and the main thread, it has a rendering graph locking mechanism. - -class AudioContext : public ActiveDOMObject, public RefCounted { -public: - static PassRefPtr create(Document*); - - virtual ~AudioContext(); - - bool isInitialized() const; - - // Returns true when initialize() was called AND all asynchronous initialization has completed. - bool isRunnable() const; - - // Document notification - virtual void stop(); - - Document* document(); // ASSERTs if document no longer exists. - bool hasDocument(); - - AudioDestinationNode* destination() { return m_destinationNode.get(); } - double currentTime() { return m_destinationNode->currentTime(); } - double sampleRate() { return m_destinationNode->sampleRate(); } - - PassRefPtr createBuffer(unsigned numberOfChannels, size_t numberOfFrames, double sampleRate); - PassRefPtr createBuffer(ArrayBuffer* arrayBuffer, bool mixToMono); - - // Keep track of this buffer so we can release memory after the context is shut down... - void refBuffer(PassRefPtr buffer); - - AudioListener* listener() { return m_listener.get(); } - - // The AudioNode create methods are called on the main thread (from JavaScript). - PassRefPtr createBufferSource(); - PassRefPtr createGainNode(); - PassRefPtr createDelayNode(); - PassRefPtr createLowPass2Filter(); - PassRefPtr createHighPass2Filter(); - PassRefPtr createPanner(); - PassRefPtr createConvolver(); - PassRefPtr createAnalyser(); - PassRefPtr createJavaScriptNode(size_t bufferSize); - PassRefPtr createChannelSplitter(); - PassRefPtr createChannelMerger(); - - AudioBus* temporaryMonoBus() { return m_temporaryMonoBus.get(); } - AudioBus* temporaryStereoBus() { return m_temporaryStereoBus.get(); } - - // When a source node has no more processing to do (has finished playing), then it tells the context to dereference it. - void notifyNodeFinishedProcessing(AudioNode*); - - // Called at the start of each render quantum. - void handlePreRenderTasks(); - - // Called at the end of each render quantum. - void handlePostRenderTasks(); - - // Called periodically at the end of each render quantum to dereference finished source nodes. - void derefFinishedSourceNodes(); - - // We reap all marked nodes at the end of each realtime render quantum in deleteMarkedNodes(). - void markForDeletion(AudioNode*); - void deleteMarkedNodes(); - - // Keeps track of the number of connections made. - void incrementConnectionCount() - { - ASSERT(isMainThread()); - m_connectionCount++; - } - - unsigned connectionCount() const { return m_connectionCount; } - - // - // Thread Safety and Graph Locking: - // - - void setAudioThread(ThreadIdentifier thread) { m_audioThread = thread; } // FIXME: check either not initialized or the same - ThreadIdentifier audioThread() const { return m_audioThread; } - bool isAudioThread() const; - - // Returns true only after the audio thread has been started and then shutdown. - bool isAudioThreadFinished() { return m_isAudioThreadFinished; } - - // mustReleaseLock is set to true if we acquired the lock in this method call and caller must unlock(), false if it was previously acquired. - void lock(bool& mustReleaseLock); - - // Returns true if we own the lock. - // mustReleaseLock is set to true if we acquired the lock in this method call and caller must unlock(), false if it was previously acquired. - bool tryLock(bool& mustReleaseLock); - - void unlock(); - - // Returns true if this thread owns the context's lock. - bool isGraphOwner() const; - - class AutoLocker { - public: - AutoLocker(AudioContext* context) - : m_context(context) - { - ASSERT(context); - context->lock(m_mustReleaseLock); - } - - ~AutoLocker() - { - if (m_mustReleaseLock) - m_context->unlock(); - } - private: - AudioContext* m_context; - bool m_mustReleaseLock; - }; - - // In AudioNode::deref() a tryLock() is used for calling finishDeref(), but if it fails keep track here. - void addDeferredFinishDeref(AudioNode*, AudioNode::RefType); - - // In the audio thread at the start of each render cycle, we'll call handleDeferredFinishDerefs(). - void handleDeferredFinishDerefs(); - - // Only accessed when the graph lock is held. - void markAudioNodeInputDirty(AudioNodeInput*); - void markAudioNodeOutputDirty(AudioNodeOutput*); - -private: - AudioContext(Document*); - void lazyInitialize(); - void uninitialize(); - - bool m_isInitialized; - bool m_isAudioThreadFinished; - bool m_isAudioThreadShutdown; - - Document* m_document; - - // The context itself keeps a reference to all source nodes. The source nodes, then reference all nodes they're connected to. - // In turn, these nodes reference all nodes they're connected to. All nodes are ultimately connected to the AudioDestinationNode. - // When the context dereferences a source node, it will be deactivated from the rendering graph along with all other nodes it is - // uniquely connected to. See the AudioNode::ref() and AudioNode::deref() methods for more details. - void refNode(AudioNode*); - void derefNode(AudioNode*); - - // When the context goes away, there might still be some sources which haven't finished playing. - // Make sure to dereference them here. - void derefUnfinishedSourceNodes(); - - RefPtr m_destinationNode; - RefPtr m_listener; - - // Only accessed in the main thread. - Vector > m_allocatedBuffers; - - // Only accessed in the audio thread. - Vector m_finishedNodes; - - // We don't use RefPtr here because AudioNode has a more complex ref() / deref() implementation - // with an optional argument for refType. We need to use the special refType: RefTypeConnection - // Either accessed when the graph lock is held, or on the main thread when the audio thread has finished. - Vector m_referencedNodes; - - // Accumulate nodes which need to be deleted at the end of a render cycle (in realtime thread) here. - Vector m_nodesToDelete; - - // Only accessed when the graph lock is held. - HashSet m_dirtyAudioNodeInputs; - HashSet m_dirtyAudioNodeOutputs; - void handleDirtyAudioNodeInputs(); - void handleDirtyAudioNodeOutputs(); - - OwnPtr m_temporaryMonoBus; - OwnPtr m_temporaryStereoBus; - - unsigned m_connectionCount; - - // Graph locking. - Mutex m_contextGraphMutex; - volatile ThreadIdentifier m_audioThread; - volatile ThreadIdentifier m_graphOwnerThread; // if the lock is held then this is the thread which owns it, otherwise == UndefinedThreadIdentifier - - // Deferred de-referencing. - struct RefInfo { - RefInfo(AudioNode* node, AudioNode::RefType refType) - : m_node(node) - , m_refType(refType) - { - } - AudioNode* m_node; - AudioNode::RefType m_refType; - }; - - // Only accessed in the audio thread. - Vector m_deferredFinishDerefList; - - // HRTF Database loader - RefPtr m_hrtfDatabaseLoader; -}; - -} // WebCore - -#endif // AudioContext_h diff --git a/WebCore/webaudio/AudioContext.idl b/WebCore/webaudio/AudioContext.idl deleted file mode 100644 index 9f0f49c..0000000 --- a/WebCore/webaudio/AudioContext.idl +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module webaudio { - interface [ - Conditional=WEB_AUDIO, - CanBeConstructed, - CustomConstructFunction, - V8CustomConstructor - ] AudioContext { - // All rendered audio ultimately connects to destination, which represents the audio hardware. - readonly attribute AudioDestinationNode destination; - - // All scheduled times are relative to this time in seconds. - readonly attribute float currentTime; - - // All AudioNodes in the context run at this sample-rate (in sample-frames per second). - readonly attribute float sampleRate; - - // All panning is relative to this listener. - readonly attribute AudioListener listener; - - AudioBuffer createBuffer(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate); - AudioBuffer createBuffer(in ArrayBuffer buffer, in boolean mixToMono); - - // Source - AudioBufferSourceNode createBufferSource(); - - // Processing nodes - AudioGainNode createGainNode(); - DelayNode createDelayNode(); - LowPass2FilterNode createLowPass2Filter(); - HighPass2FilterNode createHighPass2Filter(); - AudioPannerNode createPanner(); - ConvolverNode createConvolver(); - RealtimeAnalyserNode createAnalyser(); - JavaScriptAudioNode createJavaScriptNode(in unsigned long bufferSize); - - // Channel splitting and merging - AudioChannelSplitter createChannelSplitter(); - AudioChannelMerger createChannelMerger(); - }; -} diff --git a/WebCore/webaudio/AudioDestinationNode.cpp b/WebCore/webaudio/AudioDestinationNode.cpp deleted file mode 100644 index d2f4928..0000000 --- a/WebCore/webaudio/AudioDestinationNode.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioDestinationNode.h" - -#include "AudioBus.h" -#include "AudioContext.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" -#include - -namespace WebCore { - -AudioDestinationNode::AudioDestinationNode(AudioContext* context) - : AudioNode(context, AudioDestination::hardwareSampleRate()) - , m_currentTime(0.0) -{ - addInput(adoptPtr(new AudioNodeInput(this))); - - setType(NodeTypeDestination); - - initialize(); -} - -AudioDestinationNode::~AudioDestinationNode() -{ - uninitialize(); -} - -void AudioDestinationNode::initialize() -{ - if (isInitialized()) - return; - - double hardwareSampleRate = AudioDestination::hardwareSampleRate(); -#ifndef NDEBUG - fprintf(stderr, ">>>> hardwareSampleRate = %f\n", hardwareSampleRate); -#endif - - m_destination = AudioDestination::create(*this, hardwareSampleRate); - m_destination->start(); - - AudioNode::initialize(); -} - -void AudioDestinationNode::uninitialize() -{ - if (!isInitialized()) - return; - - m_destination->stop(); - - AudioNode::uninitialize(); -} - -// The audio hardware calls us back here to gets its input stream. -void AudioDestinationNode::provideInput(AudioBus* destinationBus, size_t numberOfFrames) -{ - context()->setAudioThread(currentThread()); - - if (!context()->isRunnable()) { - destinationBus->zero(); - return; - } - - // Let the context take care of any business at the start of each render quantum. - context()->handlePreRenderTasks(); - - // This will cause the node(s) connected to us to process, which in turn will pull on their input(s), - // all the way backwards through the rendering graph. - AudioBus* renderedBus = input(0)->pull(destinationBus, numberOfFrames); - - if (!renderedBus) - destinationBus->zero(); - else if (renderedBus != destinationBus) { - // in-place processing was not possible - so copy - destinationBus->copyFrom(*renderedBus); - } - - // Let the context take care of any business at the end of each render quantum. - context()->handlePostRenderTasks(); - - // Advance current time. - m_currentTime += numberOfFrames / sampleRate(); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioDestinationNode.h b/WebCore/webaudio/AudioDestinationNode.h deleted file mode 100644 index 4c21bb8..0000000 --- a/WebCore/webaudio/AudioDestinationNode.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioDestinationNode_h -#define AudioDestinationNode_h - -#include "AudioDestination.h" -#include "AudioNode.h" -#include "AudioSourceProvider.h" -#include -#include - -namespace WebCore { - -class AudioBus; -class AudioContext; - -class AudioDestinationNode : public AudioNode, public AudioSourceProvider { -public: - static PassRefPtr create(AudioContext* context) - { - return adoptRef(new AudioDestinationNode(context)); - } - - virtual ~AudioDestinationNode(); - - // AudioNode - virtual void process(size_t) { }; // we're pulled by hardware so this is never called - virtual void reset() { m_currentTime = 0.0; }; - virtual void initialize(); - virtual void uninitialize(); - - // The audio hardware calls here periodically to gets its input stream. - virtual void provideInput(AudioBus*, size_t numberOfFrames); - - double currentTime() { return m_currentTime; } - - double sampleRate() const { return m_destination->sampleRate(); } - - unsigned numberOfChannels() const { return 2; } // FIXME: update when multi-channel (more than stereo) is supported - -private: - AudioDestinationNode(AudioContext*); - - OwnPtr m_destination; - double m_currentTime; -}; - -} // namespace WebCore - -#endif // AudioDestinationNode_h diff --git a/WebCore/webaudio/AudioDestinationNode.idl b/WebCore/webaudio/AudioDestinationNode.idl deleted file mode 100644 index d7bf09f..0000000 --- a/WebCore/webaudio/AudioDestinationNode.idl +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] AudioDestinationNode : AudioNode { - readonly attribute long numberOfChannels; - }; -} diff --git a/WebCore/webaudio/AudioGain.h b/WebCore/webaudio/AudioGain.h deleted file mode 100644 index eb3c52d..0000000 --- a/WebCore/webaudio/AudioGain.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010 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 AudioGain_h -#define AudioGain_h - -#include "AudioParam.h" -#include - -namespace WebCore { - -class AudioGain : public AudioParam { -public: - static PassRefPtr create(const char* name, double defaultValue, double minValue, double maxValue) - { - return adoptRef(new AudioGain(name, defaultValue, minValue, maxValue)); - } - -private: - AudioGain(const char* name, double defaultValue, double minValue, double maxValue) - : AudioParam(name, defaultValue, minValue, maxValue) - { - } -}; - -} // namespace WebCore - -#endif // AudioParam_h diff --git a/WebCore/webaudio/AudioGain.idl b/WebCore/webaudio/AudioGain.idl deleted file mode 100644 index ead7c9a..0000000 --- a/WebCore/webaudio/AudioGain.idl +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] AudioGain : AudioParam { - }; -} diff --git a/WebCore/webaudio/AudioGainNode.cpp b/WebCore/webaudio/AudioGainNode.cpp deleted file mode 100644 index 5b9af07..0000000 --- a/WebCore/webaudio/AudioGainNode.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioGainNode.h" - -#include "AudioBus.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" - -namespace WebCore { - -AudioGainNode::AudioGainNode(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) - , m_lastGain(1.0) -{ - m_gain = AudioGain::create("gain", 1.0, 0.0, 1.0); - - addInput(adoptPtr(new AudioNodeInput(this))); - addOutput(adoptPtr(new AudioNodeOutput(this, 1))); - - setType(NodeTypeGain); - - initialize(); -} - -void AudioGainNode::process(size_t /*framesToProcess*/) -{ - // FIXME: there is a nice optimization to avoid processing here, and let the gain change - // happen in the summing junction input of the AudioNode we're connected to. - // Then we can avoid all of the following: - - AudioBus* outputBus = output(0)->bus(); - ASSERT(outputBus); - - // The realtime thread can't block on this lock, so we call tryLock() instead. - if (m_processLock.tryLock()) { - if (!isInitialized() || !input(0)->isConnected()) - outputBus->zero(); - else { - AudioBus* inputBus = input(0)->bus(); - - // Apply the gain with de-zippering into the output bus. - outputBus->copyWithGainFrom(*inputBus, &m_lastGain, gain()->value()); - } - - m_processLock.unlock(); - } else { - // Too bad - the tryLock() failed. We must be in the middle of re-connecting and were already outputting silence anyway... - outputBus->zero(); - } -} - -void AudioGainNode::reset() -{ - // Snap directly to desired gain. - m_lastGain = gain()->value(); -} - -// FIXME: this can go away when we do mixing with gain directly in summing junction of AudioNodeInput -// -// As soon as we know the channel count of our input, we can lazily initialize. -// Sometimes this may be called more than once with different channel counts, in which case we must safely -// uninitialize and then re-initialize with the new channel count. -void AudioGainNode::checkNumberOfChannelsForInput(AudioNodeInput* input) -{ - ASSERT(input && input == this->input(0)); - if (input != this->input(0)) - return; - - unsigned numberOfChannels = input->numberOfChannels(); - - if (isInitialized() && numberOfChannels != output(0)->numberOfChannels()) { - // We're already initialized but the channel count has changed. - // We need to be careful since we may be actively processing right now, so synchronize with process(). - MutexLocker locker(m_processLock); - uninitialize(); - } - - if (!isInitialized()) { - // This will propagate the channel count to any nodes connected further downstream in the graph. - output(0)->setNumberOfChannels(numberOfChannels); - initialize(); - } -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioGainNode.h b/WebCore/webaudio/AudioGainNode.h deleted file mode 100644 index 3710472..0000000 --- a/WebCore/webaudio/AudioGainNode.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioGainNode_h -#define AudioGainNode_h - -#include "AudioGain.h" -#include "AudioNode.h" -#include -#include - -namespace WebCore { - -class AudioContext; - -// AudioGainNode is an AudioNode with one input and one output which applies a gain (volume) change to the audio signal. -// De-zippering (smoothing) is applied when the gain value is changed dynamically. - -class AudioGainNode : public AudioNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new AudioGainNode(context, sampleRate)); - } - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void reset(); - - // Called in the main thread when the number of channels for the input may have changed. - virtual void checkNumberOfChannelsForInput(AudioNodeInput*); - - // JavaScript interface - AudioGain* gain() { return m_gain.get(); } - -private: - AudioGainNode(AudioContext*, double sampleRate); - - double m_lastGain; // for de-zippering - RefPtr m_gain; - - // This synchronizes live channel count changes which require an uninitialization / re-initialization. - // FIXME: this can go away when we implement optimization for mixing with gain directly in summing junction of AudioNodeInput. - mutable Mutex m_processLock; -}; - -} // namespace WebCore - -#endif // AudioGainNode_h diff --git a/WebCore/webaudio/AudioGainNode.idl b/WebCore/webaudio/AudioGainNode.idl deleted file mode 100644 index 3d4f40f..0000000 --- a/WebCore/webaudio/AudioGainNode.idl +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] AudioGainNode : AudioNode { - // FIXME: eventually it will be interesting to remove the readonly restriction, but need to properly deal with thread safety here. - readonly attribute AudioGain gain; - }; -} diff --git a/WebCore/webaudio/AudioListener.cpp b/WebCore/webaudio/AudioListener.cpp deleted file mode 100644 index 44fb02c..0000000 --- a/WebCore/webaudio/AudioListener.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -#include "config.h" - -#if ENABLE(WEB_AUDIO) - -#include "AudioListener.h" - -#include "AudioBus.h" - -namespace WebCore { - -AudioListener::AudioListener() - : m_position(0, 0, 0) - , m_orientation(0.0, 0.0, -1.0) - , m_upVector(0.0, 1.0, 0.0) - , m_velocity(0, 0, 0) - , m_dopplerFactor(1.0) - , m_speedOfSound(343.3) -{ -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioListener.h b/WebCore/webaudio/AudioListener.h deleted file mode 100644 index 5281a89..0000000 --- a/WebCore/webaudio/AudioListener.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2010 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 AudioListener_h -#define AudioListener_h - -#include "FloatPoint3D.h" -#include -#include - -namespace WebCore { - -// AudioListener maintains the state of the listener in the audio scene as defined in the OpenAL specification. - -class AudioListener : public RefCounted { -public: - static PassRefPtr create() - { - return adoptRef(new AudioListener()); - } - - // Position - void setPosition(double x, double y, double z) { setPosition(FloatPoint3D(x, y, z)); } - void setPosition(const FloatPoint3D &position) { m_position = position; } - const FloatPoint3D& position() const { return m_position; } - - // Orientation - void setOrientation(double x, double y, double z, double upX, double upY, double upZ) - { - setOrientation(FloatPoint3D(x, y, z)); - setUpVector(FloatPoint3D(upX, upY, upZ)); - } - void setOrientation(const FloatPoint3D &orientation) { m_orientation = orientation; } - const FloatPoint3D& orientation() const { return m_orientation; } - - // Up-vector - void setUpVector(const FloatPoint3D &upVector) { m_upVector = upVector; } - const FloatPoint3D& upVector() const { return m_upVector; } - - // Velocity - void setVelocity(double x, double y, double z) { setVelocity(FloatPoint3D(x, y, z)); } - void setVelocity(const FloatPoint3D &velocity) { m_velocity = velocity; } - const FloatPoint3D& velocity() const { return m_velocity; } - - // Doppler factor - void setDopplerFactor(double dopplerFactor) { m_dopplerFactor = dopplerFactor; } - double dopplerFactor() const { return m_dopplerFactor; } - - // Speed of sound - void setSpeedOfSound(double speedOfSound) { m_speedOfSound = speedOfSound; } - double speedOfSound() const { return m_speedOfSound; } - -private: - AudioListener(); - - // Position / Orientation - FloatPoint3D m_position; - FloatPoint3D m_orientation; - FloatPoint3D m_upVector; - - FloatPoint3D m_velocity; - - double m_dopplerFactor; - double m_speedOfSound; -}; - -} // WebCore - -#endif // AudioListener_h diff --git a/WebCore/webaudio/AudioListener.idl b/WebCore/webaudio/AudioListener.idl deleted file mode 100644 index cf6d8cf..0000000 --- a/WebCore/webaudio/AudioListener.idl +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO - ] AudioListener { - attribute float dopplerFactor; // same as OpenAL (default 1.0) - attribute float speedOfSound; // in meters / second (default 343.3) - - void setPosition(in float x, in float y, in float z); - void setOrientation(in float x, in float y, in float z, in float xUp, in float yUp, in float zUp); - void setVelocity(in float x, in float y, in float z); - }; -} diff --git a/WebCore/webaudio/AudioNode.cpp b/WebCore/webaudio/AudioNode.cpp deleted file mode 100644 index 18ddd3b..0000000 --- a/WebCore/webaudio/AudioNode.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioNode.h" - -#include "AudioContext.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" -#include - -namespace WebCore { - -AudioNode::AudioNode(AudioContext* context, double sampleRate) - : m_isInitialized(false) - , m_type(NodeTypeUnknown) - , m_context(context) - , m_sampleRate(sampleRate) - , m_lastProcessingTime(-1.0) - , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class) - , m_connectionRefCount(0) - , m_disabledRefCount(0) - , m_isMarkedForDeletion(false) - , m_isDisabled(false) -{ -#if DEBUG_AUDIONODE_REFERENCES - if (!s_isNodeCountInitialized) { - s_isNodeCountInitialized = true; - atexit(AudioNode::printNodeCounts); - } -#endif -} - -AudioNode::~AudioNode() -{ -#if DEBUG_AUDIONODE_REFERENCES - --s_nodeCount[type()]; - printf("%p: %d: AudioNode::~AudioNode() %d %d %d\n", this, type(), m_normalRefCount, m_connectionRefCount, m_disabledRefCount); -#endif -} - -void AudioNode::initialize() -{ - m_isInitialized = true; -} - -void AudioNode::uninitialize() -{ - m_isInitialized = false; -} - -void AudioNode::setType(NodeType type) -{ - m_type = type; - -#if DEBUG_AUDIONODE_REFERENCES - ++s_nodeCount[type]; -#endif -} - -void AudioNode::lazyInitialize() -{ - if (!isInitialized()) - initialize(); -} - -void AudioNode::addInput(PassOwnPtr input) -{ - m_inputs.append(input); -} - -void AudioNode::addOutput(PassOwnPtr output) -{ - m_outputs.append(output); -} - -AudioNodeInput* AudioNode::input(unsigned i) -{ - return m_inputs[i].get(); -} - -AudioNodeOutput* AudioNode::output(unsigned i) -{ - return m_outputs[i].get(); -} - -bool AudioNode::connect(AudioNode* destination, unsigned outputIndex, unsigned inputIndex) -{ - ASSERT(isMainThread()); - AudioContext::AutoLocker locker(context()); - - // Sanity check input and output indices. - if (outputIndex >= numberOfOutputs()) - return false; - if (destination && inputIndex >= destination->numberOfInputs()) - return false; - - AudioNodeOutput* output = this->output(outputIndex); - if (!destination) { - // Disconnect output from any inputs it may be currently connected to. - output->disconnectAllInputs(); - return true; - } - - AudioNodeInput* input = destination->input(inputIndex); - input->connect(output); - - // Let context know that a connection has been made. - context()->incrementConnectionCount(); - - return true; -} - -bool AudioNode::disconnect(unsigned outputIndex) -{ - ASSERT(isMainThread()); - AudioContext::AutoLocker locker(context()); - - return connect(0, outputIndex); -} - -void AudioNode::processIfNecessary(size_t framesToProcess) -{ - ASSERT(context()->isAudioThread()); - - if (!isInitialized()) - return; - - // Ensure that we only process once per rendering quantum. - // This handles the "fanout" problem where an output is connected to multiple inputs. - // The first time we're called during this time slice we process, but after that we don't want to re-process, - // instead our output(s) will already have the results cached in their bus; - double currentTime = context()->currentTime(); - if (m_lastProcessingTime != currentTime) { - m_lastProcessingTime = currentTime; // important to first update this time because of feedback loops in the rendering graph - pullInputs(framesToProcess); - process(framesToProcess); - } -} - -void AudioNode::pullInputs(size_t framesToProcess) -{ - ASSERT(context()->isAudioThread()); - - // Process all of the AudioNodes connected to our inputs. - for (unsigned i = 0; i < m_inputs.size(); ++i) - input(i)->pull(0, framesToProcess); -} - -void AudioNode::ref(RefType refType) -{ - switch (refType) { - case RefTypeNormal: - atomicIncrement(&m_normalRefCount); - break; - case RefTypeConnection: - atomicIncrement(&m_connectionRefCount); - break; - case RefTypeDisabled: - atomicIncrement(&m_disabledRefCount); - break; - default: - ASSERT_NOT_REACHED(); - } - -#if DEBUG_AUDIONODE_REFERENCES - printf("%p: %d: AudioNode::ref(%d) %d %d %d\n", this, type(), refType, m_normalRefCount, m_connectionRefCount, m_disabledRefCount); -#endif - - if (m_connectionRefCount == 1 && refType == RefTypeConnection) { - // FIXME: implement wake-up - this is an advanced feature and is not necessary in a simple implementation. - // We should not be "actively" connected to anything, but now we're "waking up" - // For example, a note which has finished playing, but is now being played again. - // Note that if this is considered a worthwhile feature to add, then an evaluation of the locking considerations must be made. - } -} - -void AudioNode::deref(RefType refType) -{ - // The actually work for deref happens completely within the audio context's graph lock. - // In the case of the audio thread, we must use a tryLock to avoid glitches. - bool hasLock = false; - bool mustReleaseLock = false; - - if (context()->isAudioThread()) { - // Real-time audio thread must not contend lock (to avoid glitches). - hasLock = context()->tryLock(mustReleaseLock); - } else { - context()->lock(mustReleaseLock); - hasLock = true; - } - - if (hasLock) { - // This is where the real deref work happens. - finishDeref(refType); - - if (mustReleaseLock) - context()->unlock(); - } else { - // We were unable to get the lock, so put this in a list to finish up later. - ASSERT(context()->isAudioThread()); - context()->addDeferredFinishDeref(this, refType); - } - - // Once AudioContext::uninitialize() is called there's no more chances for deleteMarkedNodes() to get called, so we call here. - // We can't call in AudioContext::~AudioContext() since it will never be called as long as any AudioNode is alive - // because AudioNodes keep a reference to the context. - if (context()->isAudioThreadFinished()) - context()->deleteMarkedNodes(); -} - -void AudioNode::finishDeref(RefType refType) -{ - ASSERT(context()->isGraphOwner()); - - switch (refType) { - case RefTypeNormal: - ASSERT(m_normalRefCount > 0); - atomicDecrement(&m_normalRefCount); - break; - case RefTypeConnection: - ASSERT(m_connectionRefCount > 0); - atomicDecrement(&m_connectionRefCount); - break; - case RefTypeDisabled: - ASSERT(m_disabledRefCount > 0); - atomicDecrement(&m_disabledRefCount); - break; - default: - ASSERT_NOT_REACHED(); - } - -#if DEBUG_AUDIONODE_REFERENCES - printf("%p: %d: AudioNode::deref(%d) %d %d %d\n", this, type(), refType, m_normalRefCount, m_connectionRefCount, m_disabledRefCount); -#endif - - if (!m_connectionRefCount) { - if (!m_normalRefCount && !m_disabledRefCount) { - if (!m_isMarkedForDeletion) { - // All references are gone - we need to go away. - for (unsigned i = 0; i < m_outputs.size(); ++i) - output(i)->disconnectAllInputs(); // this will deref() nodes we're connected to... - - // Mark for deletion at end of each render quantum or when context shuts down. - context()->markForDeletion(this); - m_isMarkedForDeletion = true; - } - } else if (refType == RefTypeConnection) { - if (!m_isDisabled) { - // Still may have JavaScript references, but no more "active" connection references, so put all of our outputs in a "dormant" disabled state. - // Garbage collection may take a very long time after this time, so the "dormant" disabled nodes should not bog down the rendering... - - // As far as JavaScript is concerned, our outputs must still appear to be connected. - // But internally our outputs should be disabled from the inputs they're connected to. - // disable() can recursively deref connections (and call disable()) down a whole chain of connected nodes. - - // FIXME: we special case the convolver and delay since they have a significant tail-time and shouldn't be disconnected simply - // because they no longer have any input connections. This needs to be handled more generally where AudioNodes have - // a tailTime attribute. Then the AudioNode only needs to remain "active" for tailTime seconds after there are no - // longer any active connections. - if (type() != NodeTypeConvolver && type() != NodeTypeDelay) { - m_isDisabled = true; - for (unsigned i = 0; i < m_outputs.size(); ++i) - output(i)->disable(); - } - } - } - } -} - -#if DEBUG_AUDIONODE_REFERENCES - -bool AudioNode::s_isNodeCountInitialized = false; -int AudioNode::s_nodeCount[NodeTypeEnd]; - -void AudioNode::printNodeCounts() -{ - printf("\n\n"); - printf("===========================\n"); - printf("AudioNode: reference counts\n"); - printf("===========================\n"); - - for (unsigned i = 0; i < NodeTypeEnd; ++i) - printf("%d: %d\n", i, s_nodeCount[i]); - - printf("===========================\n\n\n"); -} - -#endif // DEBUG_AUDIONODE_REFERENCES - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioNode.h b/WebCore/webaudio/AudioNode.h deleted file mode 100644 index 069407d..0000000 --- a/WebCore/webaudio/AudioNode.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioNode_h -#define AudioNode_h - -#include -#include -#include -#include - -#define DEBUG_AUDIONODE_REFERENCES 0 - -namespace WebCore { - -class AudioContext; -class AudioNodeInput; -class AudioNodeOutput; - -// An AudioNode is the basic building block for handling audio within an AudioContext. -// It may be an audio source, an intermediate processing module, or an audio destination. -// Each AudioNode can have inputs and/or outputs. An AudioSourceNode has no inputs and a single output. -// An AudioDestinationNode has one input and no outputs and represents the final destination to the audio hardware. -// Most processing nodes such as filters will have one input and one output, although multiple inputs and outputs are possible. - -class AudioNode { -public: - enum { ProcessingSizeInFrames = 128 }; - - AudioNode(AudioContext*, double sampleRate); - virtual ~AudioNode(); - - AudioContext* context() { return m_context.get(); } - - enum NodeType { - NodeTypeUnknown, - NodeTypeDestination, - NodeTypeAudioBufferSource, - NodeTypeJavaScript, - NodeTypeLowPass2Filter, - NodeTypeHighPass2Filter, - NodeTypePanner, - NodeTypeConvolver, - NodeTypeDelay, - NodeTypeGain, - NodeTypeChannelSplitter, - NodeTypeChannelMerger, - NodeTypeAnalyser, - NodeTypeEnd - }; - - NodeType type() const { return m_type; } - void setType(NodeType); - - // We handle our own ref-counting because of the threading issues and subtle nature of - // how AudioNodes can continue processing (playing one-shot sound) after there are no more - // JavaScript references to the object. - enum RefType { RefTypeNormal, RefTypeConnection, RefTypeDisabled }; - - // Can be called from main thread or context's audio thread. - void ref(RefType refType = RefTypeNormal); - void deref(RefType refType = RefTypeNormal); - - // Can be called from main thread or context's audio thread. It must be called while the context's graph lock is held. - void finishDeref(RefType refType); - - // The AudioNodeInput(s) (if any) will already have their input data available when process() is called. - // Subclasses will take this input data and put the results in the AudioBus(s) of its AudioNodeOutput(s) (if any). - // Called from context's audio thread. - virtual void process(size_t framesToProcess) = 0; - - // Resets DSP processing state (clears delay lines, filter memory, etc.) - // Called from context's audio thread. - virtual void reset() = 0; - - // No significant resources should be allocated until initialize() is called. - // Processing may not occur until a node is initialized. - virtual void initialize(); - virtual void uninitialize(); - - bool isInitialized() const { return m_isInitialized; } - void lazyInitialize(); - - unsigned numberOfInputs() const { return m_inputs.size(); } - unsigned numberOfOutputs() const { return m_outputs.size(); } - - AudioNodeInput* input(unsigned); - AudioNodeOutput* output(unsigned); - - // connect() / disconnect() return true on success. - // Called from main thread by corresponding JavaScript methods. - bool connect(AudioNode* destination, unsigned outputIndex = 0, unsigned inputIndex = 0); - bool disconnect(unsigned outputIndex = 0); - - double sampleRate() const { return m_sampleRate; } - - // processIfNecessary() is called by our output(s) when the rendering graph needs this AudioNode to process. - // This method ensures that the AudioNode will only process once per rendering time quantum even if it's called repeatedly. - // This handles the case of "fanout" where an output is connected to multiple AudioNode inputs. - // Called from context's audio thread. - void processIfNecessary(size_t framesToProcess); - - // Called when a new connection has been made to one of our inputs or the connection number of channels has changed. - // This potentially gives us enough information to perform a lazy initialization or, if necessary, a re-initialization. - // Called from main thread. - virtual void checkNumberOfChannelsForInput(AudioNodeInput*) { } - -#if DEBUG_AUDIONODE_REFERENCES - static void printNodeCounts(); -#endif - - bool isMarkedForDeletion() const { return m_isMarkedForDeletion; } - -protected: - // Inputs and outputs must be created before the AudioNode is initialized. - void addInput(PassOwnPtr); - void addOutput(PassOwnPtr); - - // Called by processIfNecessary() to cause all parts of the rendering graph connected to us to process. - // Each rendering quantum, the audio data for each of the AudioNode's inputs will be available after this method is called. - // Called from context's audio thread. - virtual void pullInputs(size_t framesToProcess); - -private: - volatile bool m_isInitialized; - NodeType m_type; - RefPtr m_context; - double m_sampleRate; - Vector > m_inputs; - Vector > m_outputs; - - double m_lastProcessingTime; - - // Ref-counting - volatile int m_normalRefCount; - volatile int m_connectionRefCount; - volatile int m_disabledRefCount; - - bool m_isMarkedForDeletion; - bool m_isDisabled; - -#if DEBUG_AUDIONODE_REFERENCES - static bool s_isNodeCountInitialized; - static int s_nodeCount[NodeTypeEnd]; -#endif -}; - -} // namespace WebCore - -#endif // AudioNode_h diff --git a/WebCore/webaudio/AudioNode.idl b/WebCore/webaudio/AudioNode.idl deleted file mode 100644 index 8d903e2..0000000 --- a/WebCore/webaudio/AudioNode.idl +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO - ] AudioNode { - readonly attribute AudioContext context; - readonly attribute unsigned long numberOfInputs; - readonly attribute unsigned long numberOfOutputs; - - [Custom] void connect(in AudioNode destination, in unsigned long output, in unsigned long input) - raises(DOMException); - - [Custom] void disconnect(in unsigned long output) - raises(DOMException); - }; -} diff --git a/WebCore/webaudio/AudioNodeInput.cpp b/WebCore/webaudio/AudioNodeInput.cpp deleted file mode 100644 index 9fd1852..0000000 --- a/WebCore/webaudio/AudioNodeInput.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioNodeInput.h" - -#include "AudioContext.h" -#include "AudioNode.h" -#include "AudioNodeOutput.h" -#include - -using namespace std; - -namespace WebCore { - -AudioNodeInput::AudioNodeInput(AudioNode* node) - : m_node(node) - , m_renderingStateNeedUpdating(false) -{ - m_monoSummingBus = adoptPtr(new AudioBus(1, AudioNode::ProcessingSizeInFrames)); - m_stereoSummingBus = adoptPtr(new AudioBus(2, AudioNode::ProcessingSizeInFrames)); -} - -void AudioNodeInput::connect(AudioNodeOutput* output) -{ - ASSERT(context()->isGraphOwner()); - - ASSERT(output && node()); - if (!output || !node()) - return; - - // Check if we're already connected to this output. - if (m_outputs.contains(output)) - return; - - output->addInput(this); - m_outputs.add(output); - changedOutputs(); - - // Sombody has just connected to us, so count it as a reference. - node()->ref(AudioNode::RefTypeConnection); -} - -void AudioNodeInput::disconnect(AudioNodeOutput* output) -{ - ASSERT(context()->isGraphOwner()); - - ASSERT(output && node()); - if (!output || !node()) - return; - - // First try to disconnect from "active" connections. - if (m_outputs.contains(output)) { - m_outputs.remove(output); - changedOutputs(); - output->removeInput(this); - node()->deref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted. - return; - } - - // Otherwise, try to disconnect from disabled connections. - if (m_disabledOutputs.contains(output)) { - m_disabledOutputs.remove(output); - output->removeInput(this); - node()->deref(AudioNode::RefTypeDisabled); // Note: it's important to return immediately after all deref() calls since the node may be deleted. - return; - } - - ASSERT_NOT_REACHED(); -} - -void AudioNodeInput::disable(AudioNodeOutput* output) -{ - ASSERT(context()->isGraphOwner()); - - ASSERT(output && node()); - if (!output || !node()) - return; - - ASSERT(m_outputs.contains(output)); - - m_disabledOutputs.add(output); - m_outputs.remove(output); - changedOutputs(); - - node()->ref(AudioNode::RefTypeDisabled); - node()->deref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted. -} - -void AudioNodeInput::enable(AudioNodeOutput* output) -{ - ASSERT(context()->isGraphOwner()); - - ASSERT(output && node()); - if (!output || !node()) - return; - - ASSERT(m_disabledOutputs.contains(output)); - - // Move output from disabled list to active list. - m_outputs.add(output); - m_disabledOutputs.remove(output); - changedOutputs(); - - node()->ref(AudioNode::RefTypeConnection); - node()->deref(AudioNode::RefTypeDisabled); // Note: it's important to return immediately after all deref() calls since the node may be deleted. -} - -void AudioNodeInput::changedOutputs() -{ - 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::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; - } -} - -unsigned AudioNodeInput::numberOfChannels() const -{ - // Find the number of channels of the connection with the largest number of channels. - unsigned maxChannels = 1; // one channel is the minimum allowed - - for (HashSet::iterator i = m_outputs.begin(); i != m_outputs.end(); ++i) { - AudioNodeOutput* output = *i; - maxChannels = max(maxChannels, output->bus()->numberOfChannels()); - } - - return maxChannels; -} - -unsigned AudioNodeInput::numberOfRenderingChannels() -{ - ASSERT(context()->isAudioThread()); - - // Find the number of channels of the rendering connection with the largest number of channels. - unsigned maxChannels = 1; // one channel is the minimum allowed - - for (unsigned i = 0; i < numberOfRenderingConnections(); ++i) - maxChannels = max(maxChannels, renderingOutput(i)->bus()->numberOfChannels()); - - return maxChannels; -} - -AudioBus* AudioNodeInput::bus() -{ - ASSERT(context()->isAudioThread()); - - // Handle single connection specially to allow for in-place processing. - if (numberOfRenderingConnections() == 1) - return renderingOutput(0)->bus(); - - // Multiple connections case (or no connections). - return internalSummingBus(); -} - -AudioBus* AudioNodeInput::internalSummingBus() -{ - ASSERT(context()->isAudioThread()); - - // We must pick a summing bus which is the right size to handle the largest connection. - switch (numberOfRenderingChannels()) { - case 1: - return m_monoSummingBus.get(); - case 2: - return m_stereoSummingBus.get(); - // FIXME: could implement more than just mono and stereo mixing in the future - } - - ASSERT_NOT_REACHED(); - return 0; -} - -void AudioNodeInput::sumAllConnections(AudioBus* summingBus, size_t framesToProcess) -{ - ASSERT(context()->isAudioThread()); - - // We shouldn't be calling this method if there's only one connection, since it's less efficient. - ASSERT(numberOfRenderingConnections() > 1); - - ASSERT(summingBus); - if (!summingBus) - return; - - summingBus->zero(); - - for (unsigned i = 0; i < numberOfRenderingConnections(); ++i) { - AudioNodeOutput* output = renderingOutput(i); - ASSERT(output); - - // Render audio from this output. - AudioBus* connectionBus = output->pull(0, framesToProcess); - - // Sum, with unity-gain. - summingBus->sumFrom(*connectionBus); - } -} - -AudioBus* AudioNodeInput::pull(AudioBus* inPlaceBus, size_t framesToProcess) -{ - ASSERT(context()->isAudioThread()); - - // Handle single connection case. - if (numberOfRenderingConnections() == 1) { - // The output will optimize processing using inPlaceBus if it's able. - AudioNodeOutput* output = this->renderingOutput(0); - return output->pull(inPlaceBus, framesToProcess); - } - - AudioBus* internalSummingBus = this->internalSummingBus(); - - if (!numberOfRenderingConnections()) { - // At least, generate silence if we're not connected to anything. - // FIXME: if we wanted to get fancy, we could propagate a 'silent hint' here to optimize the downstream graph processing. - internalSummingBus->zero(); - return internalSummingBus; - } - - // Handle multiple connections case. - sumAllConnections(internalSummingBus, framesToProcess); - - return internalSummingBus; -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioNodeInput.h b/WebCore/webaudio/AudioNodeInput.h deleted file mode 100644 index 1d90986..0000000 --- a/WebCore/webaudio/AudioNodeInput.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioNodeInput_h -#define AudioNodeInput_h - -#include "AudioBus.h" -#include "AudioNode.h" -#include -#include - -namespace WebCore { - -class AudioNode; -class AudioNodeOutput; - -// An AudioNodeInput represents an input to an AudioNode and can be connected from one or more AudioNodeOutputs. -// 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 { -public: - AudioNodeInput(AudioNode*); - - // 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*); - void disconnect(AudioNodeOutput*); - - // disable() will take the output out of the active connections list and set aside in a disabled list. - // enable() will put the output back into the active connections list. - // Must be called with the context's graph lock. - void enable(AudioNodeOutput*); - void disable(AudioNodeOutput*); - - // pull() processes all of the AudioNodes connected to us. - // In the case of multiple connections it sums the result into an internal summing bus. - // In the single connection case, it allows in-place processing where possible using inPlaceBus. - // It returns the bus which it rendered into, returning inPlaceBus if in-place processing was performed. - // Called from context's audio thread. - AudioBus* pull(AudioBus* inPlaceBus, size_t framesToProcess); - - // bus() contains the rendered audio after pull() has been called for each time quantum. - // 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(); - - // 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 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 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(); - - // m_disabledOutputs contains the AudioNodeOutputs which are disabled (will not be processed) by the audio graph rendering. - // But, from JavaScript's perspective, these outputs are still connected to us. - // Generally, these represent disabled connections from "notes" which have finished playing but are not yet garbage collected. - HashSet m_disabledOutputs; - - // Called from context's audio thread. - AudioBus* internalSummingBus(); - void sumAllConnections(AudioBus* summingBus, size_t framesToProcess); - - OwnPtr m_monoSummingBus; - OwnPtr m_stereoSummingBus; -}; - -} // namespace WebCore - -#endif // AudioNodeInput_h diff --git a/WebCore/webaudio/AudioNodeOutput.cpp b/WebCore/webaudio/AudioNodeOutput.cpp deleted file mode 100644 index 4c777e6..0000000 --- a/WebCore/webaudio/AudioNodeOutput.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioNodeOutput.h" - -#include "AudioBus.h" -#include "AudioContext.h" -#include "AudioNodeInput.h" -#include - -namespace WebCore { - -AudioNodeOutput::AudioNodeOutput(AudioNode* node, unsigned numberOfChannels) - : m_node(node) - , m_numberOfChannels(numberOfChannels) - , m_desiredNumberOfChannels(numberOfChannels) - , m_internalOutputBus(0) - , m_actualDestinationBus(0) - , m_isEnabled(true) - , m_renderingFanOutCount(0) -{ - m_monoInternalBus = adoptPtr(new AudioBus(1, AudioNode::ProcessingSizeInFrames)); - m_stereoInternalBus = adoptPtr(new AudioBus(2, AudioNode::ProcessingSizeInFrames)); - setInternalBus(); -} - -void AudioNodeOutput::setNumberOfChannels(unsigned numberOfChannels) -{ - ASSERT(context()->isGraphOwner()); - - m_desiredNumberOfChannels = numberOfChannels; - - if (context()->isAudioThread()) { - // If we're in the audio thread then we can take care of it right away (we should be at the very start or end of a rendering quantum). - updateNumberOfChannels(); - } else { - // Let the context take care of it in the audio thread in the pre and post render tasks. - context()->markAudioNodeOutputDirty(this); - } -} - -void AudioNodeOutput::setInternalBus() -{ - switch (m_numberOfChannels) { - case 0: - case 1: - m_internalOutputBus = m_monoInternalBus.get(); - break; - case 2: - m_internalOutputBus = m_stereoInternalBus.get(); - break; - default: - // FIXME: later we can fully implement more than stereo, 5.1, etc. - ASSERT_NOT_REACHED(); - } - - // This may later be changed in pull() to point to an in-place bus with the same number of channels. - m_actualDestinationBus = m_internalOutputBus; -} - -void AudioNodeOutput::updateRenderingState() -{ - updateNumberOfChannels(); - m_renderingFanOutCount = fanOutCount(); -} - -void AudioNodeOutput::updateNumberOfChannels() -{ - ASSERT(context()->isAudioThread() && context()->isGraphOwner()); - - if (m_numberOfChannels != m_desiredNumberOfChannels) { - m_numberOfChannels = m_desiredNumberOfChannels; - setInternalBus(); - propagateChannelCount(); - } -} - -void AudioNodeOutput::propagateChannelCount() -{ - ASSERT(context()->isAudioThread() && context()->isGraphOwner()); - - if (isChannelCountKnown()) { - // Announce to any nodes we're connected to that we changed our channel count for its input. - for (InputsIterator i = m_inputs.begin(); i != m_inputs.end(); ++i) { - AudioNodeInput* input = *i; - AudioNode* connectionNode = input->node(); - connectionNode->checkNumberOfChannelsForInput(input); - } - } -} - -AudioBus* AudioNodeOutput::pull(AudioBus* inPlaceBus, size_t framesToProcess) -{ - ASSERT(context()->isAudioThread()); - ASSERT(m_renderingFanOutCount > 0); - - // Causes our AudioNode to process if it hasn't already for this render quantum. - // We try to do in-place processing (using inPlaceBus) if at all possible, - // but we can't process in-place if we're connected to more than one input (fan-out > 1). - // In this case pull() is called multiple times per rendering quantum, and the processIfNecessary() call below will - // cause our node to process() only the first time, caching the output in m_internalOutputBus for subsequent calls. - - bool isInPlace = inPlaceBus && inPlaceBus->numberOfChannels() == numberOfChannels() && m_renderingFanOutCount == 1; - - // Setup the actual destination bus for processing when our node's process() method gets called in processIfNecessary() below. - m_actualDestinationBus = isInPlace ? inPlaceBus : m_internalOutputBus; - - node()->processIfNecessary(framesToProcess); - return m_actualDestinationBus; -} - -AudioBus* AudioNodeOutput::bus() const -{ - ASSERT(const_cast(this)->context()->isAudioThread()); - ASSERT(m_actualDestinationBus); - return m_actualDestinationBus; -} - -unsigned AudioNodeOutput::renderingFanOutCount() const -{ - return m_renderingFanOutCount; -} - -unsigned AudioNodeOutput::fanOutCount() -{ - ASSERT(context()->isGraphOwner()); - return m_inputs.size(); -} - -void AudioNodeOutput::addInput(AudioNodeInput* input) -{ - ASSERT(context()->isGraphOwner()); - - ASSERT(input); - if (!input) - return; - - m_inputs.add(input); -} - -void AudioNodeOutput::removeInput(AudioNodeInput* input) -{ - ASSERT(context()->isGraphOwner()); - - ASSERT(input); - if (!input) - return; - - m_inputs.remove(input); -} - -void AudioNodeOutput::disconnectAllInputs() -{ - ASSERT(context()->isGraphOwner()); - - // AudioNodeInput::disconnect() changes m_inputs by calling removeInput(). - while (!m_inputs.isEmpty()) { - AudioNodeInput* input = *m_inputs.begin(); - input->disconnect(this); - } -} - -void AudioNodeOutput::disable() -{ - ASSERT(context()->isGraphOwner()); - - if (m_isEnabled) { - for (InputsIterator i = m_inputs.begin(); i != m_inputs.end(); ++i) { - AudioNodeInput* input = *i; - input->disable(this); - } - m_isEnabled = false; - } -} - -void AudioNodeOutput::enable() -{ - ASSERT(context()->isGraphOwner()); - - if (!m_isEnabled) { - for (InputsIterator i = m_inputs.begin(); i != m_inputs.end(); ++i) { - AudioNodeInput* input = *i; - input->enable(this); - } - m_isEnabled = true; - } -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioNodeOutput.h b/WebCore/webaudio/AudioNodeOutput.h deleted file mode 100644 index 7114b38..0000000 --- a/WebCore/webaudio/AudioNodeOutput.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioNodeOutput_h -#define AudioNodeOutput_h - -#include "AudioBus.h" -#include "AudioNode.h" -#include -#include -#include - -namespace WebCore { - -class AudioContext; -class AudioNodeInput; - -// AudioNodeOutput represents a single output for an AudioNode. -// It may be connected to one or more AudioNodeInputs. - -class AudioNodeOutput { -public: - // It's OK to pass 0 for numberOfChannels in which case setNumberOfChannels() must be called later on. - AudioNodeOutput(AudioNode*, unsigned numberOfChannels); - - // Can be called from any thread. - AudioNode* node() const { return m_node; } - AudioContext* context() { return m_node->context(); } - - // Causes our AudioNode to process if it hasn't already for this render quantum. - // It returns the bus containing the processed audio for this output, returning inPlaceBus if in-place processing was possible. - // Called from context's audio thread. - AudioBus* pull(AudioBus* inPlaceBus, size_t framesToProcess); - - // bus() will contain the rendered audio after pull() is called for each rendering time quantum. - // Called from context's audio thread. - AudioBus* bus() const; - - // fanOutCount() is the number of AudioNodeInputs that we're connected to. - // This function should not be called in audio thread rendering code, instead renderingFanOutCount() should be used. - // It must be called with the context's graph lock. - unsigned fanOutCount(); - - // renderingFanOutCount() is the number of AudioNodeInputs that we're connected to during rendering. - // Unlike fanOutCount() it will not change during the course of a render quantum. - unsigned renderingFanOutCount() const; - - // It must be called with the context's graph lock. - void disconnectAllInputs(); - - void setNumberOfChannels(unsigned); - unsigned numberOfChannels() const { return m_numberOfChannels; } - bool isChannelCountKnown() const { return numberOfChannels() > 0; } - - // Disable/Enable happens when there are still JavaScript references to a node, but it has otherwise "finished" its work. - // For example, when a note has finished playing. It is kept around, because it may be played again at a later time. - // They must be called with the context's graph lock. - void disable(); - void enable(); - - // updateRenderingState() is called in the audio thread at the start or end of the render quantum to handle any recent changes to the graph state. - // It must be called with the context's graph lock. - void updateRenderingState(); - -private: - AudioNode* m_node; - - friend class AudioNodeInput; - - // These are called from AudioNodeInput. - // They must be called with the context's graph lock. - void addInput(AudioNodeInput*); - void removeInput(AudioNodeInput*); - - // setInternalBus() sets m_internalOutputBus appropriately for the number of channels. - // It is called in the constructor or in the audio thread with the context's graph lock. - void setInternalBus(); - - // Announce to any nodes we're connected to that we changed our channel count for its input. - // It must be called in the audio thread with the context's graph lock. - void propagateChannelCount(); - - // updateNumberOfChannels() is called in the audio thread at the start or end of the render quantum to pick up channel changes. - // It must be called with the context's graph lock. - void updateNumberOfChannels(); - - // m_numberOfChannels will only be changed in the audio thread. - // The main thread sets m_desiredNumberOfChannels which will later get picked up in the audio thread in updateNumberOfChannels(). - unsigned m_numberOfChannels; - unsigned m_desiredNumberOfChannels; - - // m_internalOutputBus will point to either m_monoInternalBus or m_stereoInternalBus. - // It must only be changed in the audio thread (or constructor). - AudioBus* m_internalOutputBus; - OwnPtr m_monoInternalBus; - OwnPtr m_stereoInternalBus; - - // m_actualDestinationBus is set in pull() and will either point to one of our internal busses or to the in-place bus. - // It must only be changed in the audio thread (or constructor). - AudioBus* m_actualDestinationBus; - - HashSet m_inputs; - typedef HashSet::iterator InputsIterator; - bool m_isEnabled; - - // For the purposes of rendering, keeps track of the number of inputs we're connected to. - // This value should only be changed at the very start or end of the rendering quantum. - unsigned m_renderingFanOutCount; -}; - -} // namespace WebCore - -#endif // AudioNodeOutput_h diff --git a/WebCore/webaudio/AudioPannerNode.cpp b/WebCore/webaudio/AudioPannerNode.cpp deleted file mode 100644 index 5c94763..0000000 --- a/WebCore/webaudio/AudioPannerNode.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioPannerNode.h" - -#include "AudioBufferSourceNode.h" -#include "AudioBus.h" -#include "AudioContext.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" -#include "HRTFPanner.h" -#include - -using namespace std; - -namespace WebCore { - -static void fixNANs(double &x) -{ - if (isnan(x) || isinf(x)) - x = 0.0; -} - -AudioPannerNode::AudioPannerNode(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) - , m_panningModel(Panner::PanningModelHRTF) - , m_lastGain(-1.0) - , m_connectionCount(0) -{ - addInput(adoptPtr(new AudioNodeInput(this))); - addOutput(adoptPtr(new AudioNodeOutput(this, 2))); - - m_distanceGain = AudioGain::create("distanceGain", 1.0, 0.0, 1.0); - m_coneGain = AudioGain::create("coneGain", 1.0, 0.0, 1.0); - - m_position = FloatPoint3D(0, 0, 0); - m_orientation = FloatPoint3D(1, 0, 0); - m_velocity = FloatPoint3D(0, 0, 0); - - setType(NodeTypePanner); - - initialize(); -} - -AudioPannerNode::~AudioPannerNode() -{ - uninitialize(); -} - -void AudioPannerNode::pullInputs(size_t framesToProcess) -{ - // We override pullInputs(), so we can detect new AudioSourceNodes which have connected to us when new connections are made. - // These AudioSourceNodes need to be made aware of our existence in order to handle doppler shift pitch changes. - if (m_connectionCount != context()->connectionCount()) { - m_connectionCount = context()->connectionCount(); - - // Recursively go through all nodes connected to us. - notifyAudioSourcesConnectedToNode(this); - } - - AudioNode::pullInputs(framesToProcess); -} - -void AudioPannerNode::process(size_t framesToProcess) -{ - AudioBus* destination = output(0)->bus(); - - if (!isInitialized() || !input(0)->isConnected() || !m_panner.get()) { - destination->zero(); - return; - } - - AudioBus* source = input(0)->bus(); - - if (!source) { - destination->zero(); - return; - } - - // Apply the panning effect. - double azimuth; - double elevation; - getAzimuthElevation(&azimuth, &elevation); - m_panner->pan(azimuth, elevation, source, destination, framesToProcess); - - // Get the distance and cone gain. - double totalGain = distanceConeGain(); - - // Snap to desired gain at the beginning. - if (m_lastGain == -1.0) - m_lastGain = totalGain; - - // Apply gain in-place with de-zippering. - destination->copyWithGainFrom(*destination, &m_lastGain, totalGain); -} - -void AudioPannerNode::reset() -{ - m_lastGain = -1.0; // force to snap to initial gain - if (m_panner.get()) - m_panner->reset(); -} - -void AudioPannerNode::initialize() -{ - if (isInitialized()) - return; - - m_panner = Panner::create(m_panningModel, sampleRate()); - - AudioNode::initialize(); -} - -void AudioPannerNode::uninitialize() -{ - if (!isInitialized()) - return; - - m_panner.clear(); - AudioNode::uninitialize(); -} - -AudioListener* AudioPannerNode::listener() -{ - return context()->listener(); -} - -void AudioPannerNode::setPanningModel(unsigned short model) -{ - if (!m_panner.get() || model != m_panningModel) { - OwnPtr newPanner = Panner::create(model, sampleRate()); - m_panner = newPanner.release(); - } -} - -void AudioPannerNode::getAzimuthElevation(double* outAzimuth, double* outElevation) -{ - // FIXME: we should cache azimuth and elevation (if possible), so we only re-calculate if a change has been made. - - double azimuth = 0.0; - - // Calculate the source-listener vector - FloatPoint3D listenerPosition = listener()->position(); - FloatPoint3D sourceListener = m_position - listenerPosition; - - if (sourceListener.isZero()) { - // degenerate case if source and listener are at the same point - *outAzimuth = 0.0; - *outElevation = 0.0; - return; - } - - sourceListener.normalize(); - - // Align axes - FloatPoint3D listenerFront = listener()->orientation(); - FloatPoint3D listenerUp = listener()->upVector(); - FloatPoint3D listenerRight = listenerFront.cross(listenerUp); - listenerRight.normalize(); - - FloatPoint3D listenerFrontNorm = listenerFront; - listenerFrontNorm.normalize(); - - FloatPoint3D up = listenerRight.cross(listenerFrontNorm); - - double upProjection = sourceListener.dot(up); - - FloatPoint3D projectedSource = sourceListener - upProjection * up; - projectedSource.normalize(); - - azimuth = 180.0 * acos(projectedSource.dot(listenerRight)) / piDouble; - fixNANs(azimuth); // avoid illegal values - - // Source in front or behind the listener - double frontBack = projectedSource.dot(listenerFrontNorm); - if (frontBack < 0.0) - azimuth = 360.0 - azimuth; - - // Make azimuth relative to "front" and not "right" listener vector - if ((azimuth >= 0.0) && (azimuth <= 270.0)) - azimuth = 90.0 - azimuth; - else - azimuth = 450.0 - azimuth; - - // Elevation - double elevation = 90.0 - 180.0 * acos(sourceListener.dot(up)) / piDouble; - fixNANs(azimuth); // avoid illegal values - - if (elevation > 90.0) - elevation = 180.0 - elevation; - else if (elevation < -90.0) - elevation = -180.0 - elevation; - - if (outAzimuth) - *outAzimuth = azimuth; - if (outElevation) - *outElevation = elevation; -} - -float AudioPannerNode::dopplerRate() -{ - double dopplerShift = 1.0; - - // FIXME: optimize for case when neither source nor listener has changed... - double dopplerFactor = listener()->dopplerFactor(); - - if (dopplerFactor > 0.0) { - double speedOfSound = listener()->speedOfSound(); - - const FloatPoint3D &sourceVelocity = m_velocity; - const FloatPoint3D &listenerVelocity = listener()->velocity(); - - // Don't bother if both source and listener have no velocity - bool sourceHasVelocity = !sourceVelocity.isZero(); - bool listenerHasVelocity = !listenerVelocity.isZero(); - - if (sourceHasVelocity || listenerHasVelocity) { - // Calculate the source to listener vector - FloatPoint3D listenerPosition = listener()->position(); - FloatPoint3D sourceToListener = m_position - listenerPosition; - - double sourceListenerMagnitude = sourceToListener.length(); - - double listenerProjection = sourceToListener.dot(listenerVelocity) / sourceListenerMagnitude; - double sourceProjection = sourceToListener.dot(sourceVelocity) / sourceListenerMagnitude; - - listenerProjection = -listenerProjection; - sourceProjection = -sourceProjection; - - double scaledSpeedOfSound = speedOfSound / dopplerFactor; - listenerProjection = min(listenerProjection, scaledSpeedOfSound); - sourceProjection = min(sourceProjection, scaledSpeedOfSound); - - dopplerShift = ((speedOfSound - dopplerFactor * listenerProjection) / (speedOfSound - dopplerFactor * sourceProjection)); - fixNANs(dopplerShift); // avoid illegal values - - // Limit the pitch shifting to 4 octaves up and 3 octaves down. - if (dopplerShift > 16.0) - dopplerShift = 16.0; - else if (dopplerShift < 0.125) - dopplerShift = 0.125; - } - } - - return static_cast(dopplerShift); -} - -float AudioPannerNode::distanceConeGain() -{ - FloatPoint3D listenerPosition = listener()->position(); - - double listenerDistance = m_position.distanceTo(listenerPosition); - double distanceGain = m_distanceEffect.gain(listenerDistance); - - m_distanceGain->setValue(static_cast(distanceGain)); - - // FIXME: could optimize by caching coneGain - double coneGain = m_coneEffect.gain(m_position, m_orientation, listenerPosition); - - m_coneGain->setValue(static_cast(coneGain)); - - return float(distanceGain * coneGain); -} - -void AudioPannerNode::notifyAudioSourcesConnectedToNode(AudioNode* node) -{ - ASSERT(node); - if (!node) - return; - - // First check if this node is an AudioBufferSourceNode. If so, let it know about us so that doppler shift pitch can be taken into account. - if (node->type() == NodeTypeAudioBufferSource) { - AudioBufferSourceNode* bufferSourceNode = reinterpret_cast(node); - bufferSourceNode->setPannerNode(this); - } else { - // Go through all inputs to this node. - for (unsigned i = 0; i < node->numberOfInputs(); ++i) { - AudioNodeInput* input = node->input(i); - - // For each input, go through all of its connections, looking for AudioBufferSourceNodes. - for (unsigned j = 0; j < input->numberOfRenderingConnections(); ++j) { - AudioNodeOutput* connectedOutput = input->renderingOutput(j); - AudioNode* connectedNode = connectedOutput->node(); - notifyAudioSourcesConnectedToNode(connectedNode); // recurse - } - } - } -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioPannerNode.h b/WebCore/webaudio/AudioPannerNode.h deleted file mode 100644 index 61e34a9..0000000 --- a/WebCore/webaudio/AudioPannerNode.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioPannerNode_h -#define AudioPannerNode_h - -#include "AudioBus.h" -#include "AudioGain.h" -#include "AudioListener.h" -#include "AudioNode.h" -#include "Cone.h" -#include "Distance.h" -#include "FloatPoint3D.h" -#include "Panner.h" -#include - -namespace WebCore { - -// AudioPannerNode is an AudioNode with one input and one output. -// It positions a sound in 3D space, with the exact effect dependent on the panning model. -// It has a position and an orientation in 3D space which is relative to the position and orientation of the context's AudioListener. -// A distance effect will attenuate the gain as the position moves away from the listener. -// A cone effect will attenuate the gain as the orientation moves away from the listener. -// All of these effects follow the OpenAL specification very closely. - -class AudioPannerNode : public AudioNode { -public: - // These must be defined as in the .idl file and must match those in the Panner class. - enum { - EQUALPOWER = 0, - HRTF = 1, - SOUNDFIELD = 2, - }; - - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new AudioPannerNode(context, sampleRate)); - } - - virtual ~AudioPannerNode(); - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void pullInputs(size_t framesToProcess); - virtual void reset(); - virtual void initialize(); - virtual void uninitialize(); - - // Listener - AudioListener* listener(); - - // Panning model - unsigned short panningModel() const { return m_panningModel; } - void setPanningModel(unsigned short); - - // Position - FloatPoint3D position() const { return m_position; } - void setPosition(float x, float y, float z) { m_position = FloatPoint3D(x, y, z); } - - // Orientation - FloatPoint3D orientation() const { return m_position; } - void setOrientation(float x, float y, float z) { m_orientation = FloatPoint3D(x, y, z); } - - // Velocity - FloatPoint3D velocity() const { return m_velocity; } - void setVelocity(float x, float y, float z) { m_velocity = FloatPoint3D(x, y, z); } - - // Distance parameters - unsigned short distanceModel() { return m_distanceEffect.model(); } - void setDistanceModel(unsigned short model) { m_distanceEffect.setModel(static_cast(model), true); } - - float refDistance() { return static_cast(m_distanceEffect.refDistance()); } - void setRefDistance(float refDistance) { m_distanceEffect.setRefDistance(refDistance); } - - float maxDistance() { return static_cast(m_distanceEffect.maxDistance()); } - void setMaxDistance(float maxDistance) { m_distanceEffect.setMaxDistance(maxDistance); } - - float rolloffFactor() { return static_cast(m_distanceEffect.rolloffFactor()); } - void setRolloffFactor(float rolloffFactor) { m_distanceEffect.setRolloffFactor(rolloffFactor); } - - // Sound cones - angles in degrees - float coneInnerAngle() const { return static_cast(m_coneEffect.innerAngle()); } - void setConeInnerAngle(float angle) { m_coneEffect.setInnerAngle(angle); } - - float coneOuterAngle() const { return static_cast(m_coneEffect.outerAngle()); } - void setConeOuterAngle(float angle) { m_coneEffect.setOuterAngle(angle); } - - float coneOuterGain() const { return static_cast(m_coneEffect.outerGain()); } - void setConeOuterGain(float angle) { m_coneEffect.setOuterGain(angle); } - - void getAzimuthElevation(double* outAzimuth, double* outElevation); - float dopplerRate(); - - // Accessors for dynamically calculated gain values. - AudioGain* distanceGain() { return m_distanceGain.get(); } - AudioGain* coneGain() { return m_coneGain.get(); } - -private: - AudioPannerNode(AudioContext*, double sampleRate); - - // Returns the combined distance and cone gain attenuation. - float distanceConeGain(); - - // Notifies any AudioBufferSourceNodes connected to us either directly or indirectly about our existence. - // This is in order to handle the pitch change necessary for the doppler shift. - void notifyAudioSourcesConnectedToNode(AudioNode*); - - OwnPtr m_panner; - unsigned m_panningModel; - - FloatPoint3D m_position; - FloatPoint3D m_orientation; - FloatPoint3D m_velocity; - - // Gain - RefPtr m_distanceGain; - RefPtr m_coneGain; - DistanceEffect m_distanceEffect; - ConeEffect m_coneEffect; - double m_lastGain; - - unsigned m_connectionCount; -}; - -} // namespace WebCore - -#endif // AudioPannerNode_h diff --git a/WebCore/webaudio/AudioPannerNode.idl b/WebCore/webaudio/AudioPannerNode.idl deleted file mode 100644 index 2db093d..0000000 --- a/WebCore/webaudio/AudioPannerNode.idl +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO, - GenerateConstructor, - GenerateToJS - ] AudioPannerNode : AudioNode { - // Panning model - const unsigned short EQUALPOWER = 0; - const unsigned short HRTF = 1; - const unsigned short SOUNDFIELD = 2; - - // Default model for stereo is HRTF - attribute unsigned long panningModel; // FIXME: use unsigned short when glue generation supports it - - // Uses a 3D cartesian coordinate system - void setPosition(in float x, in float y, in float z); - void setOrientation(in float x, in float y, in float z); - void setVelocity(in float x, in float y, in float z); - - // Distance model - attribute unsigned long distanceModel; // FIXME: use unsigned short when glue generation supports it - attribute float refDistance; - attribute float maxDistance; - attribute float rolloffFactor; - - // Directional sound cone - attribute float coneInnerAngle; - attribute float coneOuterAngle; - attribute float coneOuterGain; - - // Dynamically calculated gain values - readonly attribute AudioGain coneGain; - readonly attribute AudioGain distanceGain; - }; -} diff --git a/WebCore/webaudio/AudioParam.cpp b/WebCore/webaudio/AudioParam.cpp deleted file mode 100644 index dcf918f..0000000 --- a/WebCore/webaudio/AudioParam.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2010 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 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. - */ - -#include "config.h" - -#if ENABLE(WEB_AUDIO) - -#include "AudioParam.h" - -#include - -namespace WebCore { - -const double AudioParam::DefaultSmoothingConstant = 0.05; -const double AudioParam::SnapThreshold = 0.001; - -void AudioParam::setValue(float value) -{ - // Check against JavaScript giving us bogus floating-point values. - // Don't ASSERT, since this can happen if somebody writes bad JS. - if (!isnan(value) && !isinf(value)) - m_value = value; -} - -bool AudioParam::smooth() -{ - if (m_smoothedValue == m_value) { - // Smoothed value has already approached and snapped to value. - return true; - } - - // Exponential approach - m_smoothedValue += (m_value - m_smoothedValue) * m_smoothingConstant; - - // If we get close enough then snap to actual value. - if (fabs(m_smoothedValue - m_value) < SnapThreshold) // FIXME: the threshold needs to be adjustable depending on range - but this is OK general purpose value. - m_smoothedValue = m_value; - - return false; -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioParam.h b/WebCore/webaudio/AudioParam.h deleted file mode 100644 index 88b7615..0000000 --- a/WebCore/webaudio/AudioParam.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010 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 AudioParam_h -#define AudioParam_h - -#include "PlatformString.h" -#include -#include -#include - -namespace WebCore { - -class AudioParam : public RefCounted { -public: - static const double DefaultSmoothingConstant; - static const double SnapThreshold; - - static PassRefPtr create(const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0) - { - return adoptRef(new AudioParam(name, defaultValue, minValue, maxValue, units)); - } - - AudioParam(const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0) - : m_name(name) - , m_value(defaultValue) - , m_defaultValue(defaultValue) - , m_minValue(minValue) - , m_maxValue(maxValue) - , m_units(units) - , m_smoothedValue(defaultValue) - , m_smoothingConstant(DefaultSmoothingConstant) - { - } - - float value() const { return static_cast(m_value); } - - void setValue(float); - - String name() const { return m_name; } - - float minValue() const { return static_cast(m_minValue); } - float maxValue() const { return static_cast(m_maxValue); } - float defaultValue() const { return static_cast(m_defaultValue); } - unsigned units() const { return m_units; } - - // Value smoothing: - - // When a new value is set with setValue(), in our internal use of the parameter we don't immediately jump to it. - // Instead we smoothly approach this value to avoid glitching. - float smoothedValue() const { return static_cast(m_smoothedValue); } - - // Smoothly exponentially approaches to (de-zippers) the desired value. - // Returns true if smoothed value has already snapped exactly to value. - bool smooth(); - - void resetSmoothedValue() { m_smoothedValue = m_value; } - void setSmoothingConstant(double k) { m_smoothingConstant = k; } - -private: - String m_name; - double m_value; - double m_defaultValue; - double m_minValue; - double m_maxValue; - unsigned m_units; - - // Smoothing (de-zippering) - double m_smoothedValue; - double m_smoothingConstant; -}; - -} // namespace WebCore - -#endif // AudioParam_h diff --git a/WebCore/webaudio/AudioParam.idl b/WebCore/webaudio/AudioParam.idl deleted file mode 100644 index ff2598e..0000000 --- a/WebCore/webaudio/AudioParam.idl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -module webaudio { - interface [ - Conditional=WEB_AUDIO - ] AudioParam { - attribute float value; - readonly attribute float minValue; - readonly attribute float maxValue; - readonly attribute float defaultValue; - - readonly attribute DOMString name; - - // FIXME: Could define units constants here (seconds, decibels, cents, etc.)... - readonly attribute unsigned short units; - }; -} diff --git a/WebCore/webaudio/AudioProcessingEvent.cpp b/WebCore/webaudio/AudioProcessingEvent.cpp deleted file mode 100644 index 54ce521..0000000 --- a/WebCore/webaudio/AudioProcessingEvent.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2010, 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 "AudioProcessingEvent.h" - -#include "AudioBuffer.h" -#include "EventNames.h" - -namespace WebCore { - -PassRefPtr AudioProcessingEvent::create(PassRefPtr inputBuffer, PassRefPtr outputBuffer) -{ - return adoptRef(new AudioProcessingEvent(inputBuffer, outputBuffer)); -} - -AudioProcessingEvent::AudioProcessingEvent(PassRefPtr inputBuffer, PassRefPtr outputBuffer) - : Event(eventNames().audioprocessEvent, true, false) - , m_inputBuffer(inputBuffer) - , m_outputBuffer(outputBuffer) -{ -} - -AudioProcessingEvent::~AudioProcessingEvent() -{ -} - -bool AudioProcessingEvent::isAudioProcessingEvent() const -{ - return true; -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/AudioProcessingEvent.h b/WebCore/webaudio/AudioProcessingEvent.h deleted file mode 100644 index a88669c..0000000 --- a/WebCore/webaudio/AudioProcessingEvent.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2010, 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 AudioProcessingEvent_h -#define AudioProcessingEvent_h - -#include "AudioBuffer.h" -#include "Event.h" -#include -#include - -namespace WebCore { - -class AudioBuffer; - -class AudioProcessingEvent : public Event { -public: - static PassRefPtr create(PassRefPtr inputBuffer, PassRefPtr outputBuffer); - - virtual ~AudioProcessingEvent(); - - virtual bool isAudioProcessingEvent() const; - - AudioBuffer* inputBuffer() { return m_inputBuffer.get(); } - AudioBuffer* outputBuffer() { return m_outputBuffer.get(); } - -private: - AudioProcessingEvent(PassRefPtr inputBuffer, PassRefPtr outputBuffer); - - RefPtr m_inputBuffer; - RefPtr m_outputBuffer; -}; - -} // namespace WebCore - -#endif // AudioProcessingEvent_h diff --git a/WebCore/webaudio/AudioProcessingEvent.idl b/WebCore/webaudio/AudioProcessingEvent.idl deleted file mode 100644 index c2f8a83..0000000 --- a/WebCore/webaudio/AudioProcessingEvent.idl +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] AudioProcessingEvent : Event { - readonly attribute AudioBuffer inputBuffer; - readonly attribute AudioBuffer outputBuffer; - }; -} diff --git a/WebCore/webaudio/AudioSourceNode.h b/WebCore/webaudio/AudioSourceNode.h deleted file mode 100644 index 6091371..0000000 --- a/WebCore/webaudio/AudioSourceNode.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2010 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 AudioSourceNode_h -#define AudioSourceNode_h - -#include "AudioNode.h" - -namespace WebCore { - -class AudioSourceNode : public AudioNode { -public: - AudioSourceNode(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) - { - } -}; - -} // namespace WebCore - -#endif // AudioSourceNode_h diff --git a/WebCore/webaudio/AudioSourceNode.idl b/WebCore/webaudio/AudioSourceNode.idl deleted file mode 100644 index ec3c356..0000000 --- a/WebCore/webaudio/AudioSourceNode.idl +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO - ] AudioSourceNode : AudioNode { - }; -} diff --git a/WebCore/webaudio/BiquadDSPKernel.cpp b/WebCore/webaudio/BiquadDSPKernel.cpp deleted file mode 100644 index a4b28be..0000000 --- a/WebCore/webaudio/BiquadDSPKernel.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2010, 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 "BiquadDSPKernel.h" - -#include "BiquadProcessor.h" - -namespace WebCore { - -void BiquadDSPKernel::process(const float* source, float* destination, size_t framesToProcess) -{ - ASSERT(source && destination && biquadProcessor()); - - // Recompute filter coefficients if any of the parameters have changed. - // FIXME: as an optimization, implement a way that a Biquad object can simply copy its internal filter coefficients from another Biquad object. - // Then re-factor this code to only run for the first BiquadDSPKernel of each BiquadProcessor. - if (biquadProcessor()->filterCoefficientsDirty()) { - double value1 = biquadProcessor()->parameter1()->smoothedValue(); - double value2 = biquadProcessor()->parameter2()->smoothedValue(); - - // Convert from Hertz to normalized frequency 0 -> 1. - double nyquist = this->nyquist(); - double normalizedValue1 = value1 / nyquist; - - // Configure the biquad with the new filter parameters for the appropriate type of filter. - switch (biquadProcessor()->type()) { - case BiquadProcessor::LowPass2: - m_biquad.setLowpassParams(normalizedValue1, value2); - break; - - case BiquadProcessor::HighPass2: - m_biquad.setHighpassParams(normalizedValue1, value2); - break; - - case BiquadProcessor::LowShelf: - m_biquad.setLowShelfParams(normalizedValue1, value2); - break; - - // FIXME: add other biquad filter types... - case BiquadProcessor::Peaking: - case BiquadProcessor::Allpass: - case BiquadProcessor::HighShelf: - break; - } - } - - m_biquad.process(source, destination, framesToProcess); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/BiquadDSPKernel.h b/WebCore/webaudio/BiquadDSPKernel.h deleted file mode 100644 index 47d0f34..0000000 --- a/WebCore/webaudio/BiquadDSPKernel.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010, 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 BiquadDSPKernel_h -#define BiquadDSPKernel_h - -#include "AudioDSPKernel.h" -#include "Biquad.h" -#include "BiquadProcessor.h" - -namespace WebCore { - -class BiquadProcessor; - -// BiquadDSPKernel is an AudioDSPKernel and is responsible for filtering one channel of a BiquadProcessor using a Biquad object. - -class BiquadDSPKernel : public AudioDSPKernel { -public: - BiquadDSPKernel(BiquadProcessor* processor) - : AudioDSPKernel(processor) - { - } - - // AudioDSPKernel - virtual void process(const float* source, float* dest, size_t framesToProcess); - virtual void reset() { m_biquad.reset(); } - -protected: - Biquad m_biquad; - BiquadProcessor* biquadProcessor() { return static_cast(processor()); } -}; - -} // namespace WebCore - -#endif // BiquadDSPKernel_h diff --git a/WebCore/webaudio/BiquadProcessor.cpp b/WebCore/webaudio/BiquadProcessor.cpp deleted file mode 100644 index 97a480e..0000000 --- a/WebCore/webaudio/BiquadProcessor.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2010, 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 "BiquadProcessor.h" - -#include "BiquadDSPKernel.h" - -namespace WebCore { - -BiquadProcessor::BiquadProcessor(FilterType type, double sampleRate, size_t numberOfChannels, bool autoInitialize) - : AudioDSPKernelProcessor(sampleRate, numberOfChannels) - , m_type(type) - , m_parameter1(0) - , m_parameter2(0) - , m_parameter3(0) - , m_filterCoefficientsDirty(true) -{ - double nyquist = 0.5 * this->sampleRate(); - - switch (type) { - // Highpass and lowpass share the same parameters and only differ in filter type. - case LowPass2: - case HighPass2: - m_parameter1 = AudioParam::create("frequency", 350.0, 20.0, nyquist); - m_parameter2 = AudioParam::create("resonance", 0.0, -20.0, 20.0); - m_parameter3 = AudioParam::create("unused", 0.0, 0.0, 1.0); - break; - - case Peaking: - m_parameter1 = AudioParam::create("frequency", 2500.0, 20.0, nyquist); - m_parameter2 = AudioParam::create("gain", 0.0, -20.0, 20.0); - m_parameter3 = AudioParam::create("Q", 0.5, 0.0, 1000.0); - break; - case Allpass: - m_parameter1 = AudioParam::create("frequency", 2500.0, 20.0, nyquist); - m_parameter2 = AudioParam::create("Q", 0.5, 0.0, 1000.0); - m_parameter3 = AudioParam::create("unused", 0.0, 0.0, 1.0); - break; - case LowShelf: - m_parameter1 = AudioParam::create("frequency", 80.0, 20.0, nyquist); - m_parameter2 = AudioParam::create("gain", 0.0, 0.0, 1.0); - m_parameter3 = AudioParam::create("unused", 0.0, 0.0, 1.0); - break; - case HighShelf: - m_parameter1 = AudioParam::create("frequency", 10000.0, 20.0, nyquist); - m_parameter2 = AudioParam::create("gain", 0.0, 0.0, 1.0); - m_parameter3 = AudioParam::create("unused", 0.0, 0.0, 1.0); - break; - } - - if (autoInitialize) - initialize(); -} - -BiquadProcessor::~BiquadProcessor() -{ - if (isInitialized()) - uninitialize(); -} - -PassOwnPtr BiquadProcessor::createKernel() -{ - return adoptPtr(new BiquadDSPKernel(this)); -} - -void BiquadProcessor::process(AudioBus* source, AudioBus* destination, size_t framesToProcess) -{ - if (!isInitialized()) { - destination->zero(); - return; - } - - // Deal with smoothing / de-zippering. Start out assuming filter parameters are not changing. - // The BiquadDSPKernel objects rely on this value to see if they need to re-compute their internal filter coefficients. - m_filterCoefficientsDirty = false; - - if (m_hasJustReset) { - // Snap to exact values first time after reset, then smooth for subsequent changes. - m_parameter1->resetSmoothedValue(); - m_parameter2->resetSmoothedValue(); - m_parameter3->resetSmoothedValue(); - m_filterCoefficientsDirty = true; - m_hasJustReset = false; - } else { - // Smooth all of the filter parameters. If they haven't yet converged to their target value then mark coefficients as dirty. - bool isStable1 = m_parameter1->smooth(); - bool isStable2 = m_parameter2->smooth(); - bool isStable3 = m_parameter3->smooth(); - if (!(isStable1 && isStable2 && isStable3)) - m_filterCoefficientsDirty = true; - } - - // For each channel of our input, process using the corresponding BiquadDSPKernel into the output channel. - for (unsigned i = 0; i < m_kernels.size(); ++i) - m_kernels[i]->process(source->channel(i)->data(), destination->channel(i)->data(), framesToProcess); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/BiquadProcessor.h b/WebCore/webaudio/BiquadProcessor.h deleted file mode 100644 index 55dca33..0000000 --- a/WebCore/webaudio/BiquadProcessor.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2010, 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 BiquadProcessor_h -#define BiquadProcessor_h - -#include "AudioDSPKernel.h" -#include "AudioDSPKernelProcessor.h" -#include "AudioNode.h" -#include "AudioParam.h" -#include "Biquad.h" -#include - -namespace WebCore { - -// BiquadProcessor is an AudioDSPKernelProcessor which uses Biquad objects to implement several common filters. - -class BiquadProcessor : public AudioDSPKernelProcessor { -public: - enum FilterType { - LowPass2, - HighPass2, - Peaking, - Allpass, - LowShelf, - HighShelf - }; - - BiquadProcessor(FilterType, double sampleRate, size_t numberOfChannels, bool autoInitialize = true); - virtual ~BiquadProcessor(); - - virtual PassOwnPtr createKernel(); - - virtual void process(AudioBus* source, AudioBus* destination, size_t framesToProcess); - - bool filterCoefficientsDirty() const { return m_filterCoefficientsDirty; } - - AudioParam* parameter1() { return m_parameter1.get(); } - AudioParam* parameter2() { return m_parameter2.get(); } - AudioParam* parameter3() { return m_parameter3.get(); } - - FilterType type() const { return m_type; } - -private: - FilterType m_type; - - RefPtr m_parameter1; - RefPtr m_parameter2; - RefPtr m_parameter3; - - // so DSP kernels know when to re-compute coefficients - bool m_filterCoefficientsDirty; -}; - -} // namespace WebCore - -#endif // BiquadProcessor_h diff --git a/WebCore/webaudio/ConvolverNode.cpp b/WebCore/webaudio/ConvolverNode.cpp deleted file mode 100644 index c778a41..0000000 --- a/WebCore/webaudio/ConvolverNode.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2010, 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 "ConvolverNode.h" - -#include "AudioBuffer.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" -#include "Reverb.h" - -// Note about empirical tuning: -// The maximum FFT size affects reverb performance and accuracy. -// If the reverb is single-threaded and processes entirely in the real-time audio thread, -// it's important not to make this too high. In this case 8192 is a good value. -// But, the Reverb object is multi-threaded, so we want this as high as possible without losing too much accuracy. -// Very large FFTs will have worse phase errors. Given these constraints 16384 is a good compromise. -const size_t MaxFFTSize = 16384; - -namespace WebCore { - -ConvolverNode::ConvolverNode(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) -{ - addInput(adoptPtr(new AudioNodeInput(this))); - addOutput(adoptPtr(new AudioNodeOutput(this, 2))); - - setType(NodeTypeConvolver); - - initialize(); -} - -ConvolverNode::~ConvolverNode() -{ - uninitialize(); -} - -void ConvolverNode::process(size_t framesToProcess) -{ - AudioBus* outputBus = output(0)->bus(); - ASSERT(outputBus); - - // Synchronize with possible dynamic changes to the impulse response. - if (m_processLock.tryLock()) { - if (!isInitialized() || !m_reverb.get()) - outputBus->zero(); - else { - // Process using the convolution engine. - // Note that we can handle the case where nothing is connected to the input, in which case we'll just feed silence into the convolver. - // FIXME: If we wanted to get fancy we could try to factor in the 'tail time' and stop processing once the tail dies down if - // we keep getting fed silence. - m_reverb->process(input(0)->bus(), outputBus, framesToProcess); - } - - m_processLock.unlock(); - } else { - // Too bad - the tryLock() failed. We must be in the middle of setting a new impulse response. - outputBus->zero(); - } -} - -void ConvolverNode::reset() -{ - MutexLocker locker(m_processLock); - if (m_reverb.get()) - m_reverb->reset(); -} - -void ConvolverNode::initialize() -{ - if (isInitialized()) - return; - - AudioNode::initialize(); -} - -void ConvolverNode::uninitialize() -{ - if (!isInitialized()) - return; - - m_reverb.clear(); - AudioNode::uninitialize(); -} - -void ConvolverNode::setBuffer(AudioBuffer* buffer) -{ - ASSERT(isMainThread()); - - ASSERT(buffer); - if (!buffer) - return; - - unsigned numberOfChannels = buffer->numberOfChannels(); - size_t bufferLength = buffer->length(); - - // The current implementation supports up to four channel impulse responses, which are interpreted as true-stereo (see Reverb class). - bool isBufferGood = numberOfChannels > 0 && numberOfChannels <= 4 && bufferLength; - ASSERT(isBufferGood); - if (!isBufferGood) - return; - - // Wrap the AudioBuffer by an AudioBus. It's an efficient pointer set and not a memcpy(). - // This memory is simply used in the Reverb constructor and no reference to it is kept for later use in that class. - AudioBus bufferBus(numberOfChannels, bufferLength, false); - for (unsigned i = 0; i < numberOfChannels; ++i) - bufferBus.setChannelMemory(i, buffer->getChannelData(i)->data(), bufferLength); - - // Create the reverb with the given impulse response. - OwnPtr reverb = adoptPtr(new Reverb(&bufferBus, AudioNode::ProcessingSizeInFrames, MaxFFTSize, 2, true)); - - { - // Synchronize with process(). - MutexLocker locker(m_processLock); - m_reverb = reverb.release(); - m_buffer = buffer; - } -} - -AudioBuffer* ConvolverNode::buffer() -{ - ASSERT(isMainThread()); - return m_buffer.get(); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/ConvolverNode.h b/WebCore/webaudio/ConvolverNode.h deleted file mode 100644 index 7b71ba9..0000000 --- a/WebCore/webaudio/ConvolverNode.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2010, 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 ConvolverNode_h -#define ConvolverNode_h - -#include "AudioNode.h" -#include -#include -#include - -namespace WebCore { - -class AudioBuffer; -class Reverb; - -class ConvolverNode : public AudioNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new ConvolverNode(context, sampleRate)); - } - - virtual ~ConvolverNode(); - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void reset(); - virtual void initialize(); - virtual void uninitialize(); - - // Impulse responses - void setBuffer(AudioBuffer*); - AudioBuffer* buffer(); - -private: - ConvolverNode(AudioContext*, double sampleRate); - - OwnPtr m_reverb; - RefPtr m_buffer; - - // This synchronizes dynamic changes to the convolution impulse response with process(). - mutable Mutex m_processLock; -}; - -} // namespace WebCore - -#endif // ConvolverNode_h diff --git a/WebCore/webaudio/ConvolverNode.idl b/WebCore/webaudio/ConvolverNode.idl deleted file mode 100644 index d3eb475..0000000 --- a/WebCore/webaudio/ConvolverNode.idl +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - // A linear convolution effect - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] ConvolverNode : AudioNode { - attribute [JSCCustomSetter] AudioBuffer buffer; - }; -} diff --git a/WebCore/webaudio/DelayDSPKernel.cpp b/WebCore/webaudio/DelayDSPKernel.cpp deleted file mode 100644 index 9cb0450..0000000 --- a/WebCore/webaudio/DelayDSPKernel.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2010, 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 "DelayDSPKernel.h" - -#include "AudioUtilities.h" -#include - -using namespace std; - -const double DefaultMaxDelayTime = 1.0; -const double SmoothingTimeConstant = 0.020; // 20ms - -namespace WebCore { - -DelayDSPKernel::DelayDSPKernel(DelayProcessor* processor) - : AudioDSPKernel(processor) - , m_maxDelayTime(DefaultMaxDelayTime) - , m_writeIndex(0) - , m_firstTime(true) -{ - ASSERT(processor && processor->sampleRate() > 0); - if (!processor) - return; - - m_buffer.resize(static_cast(processor->sampleRate() * DefaultMaxDelayTime)); - m_buffer.zero(); - - m_smoothingRate = AudioUtilities::discreteTimeConstantForSampleRate(SmoothingTimeConstant, processor->sampleRate()); -} - -DelayDSPKernel::DelayDSPKernel(double maxDelayTime, double sampleRate) - : AudioDSPKernel(sampleRate) - , m_maxDelayTime(maxDelayTime) - , m_writeIndex(0) - , m_firstTime(true) -{ - ASSERT(maxDelayTime > 0.0); - if (maxDelayTime <= 0.0) - return; - - size_t bufferLength = static_cast(sampleRate * maxDelayTime); - ASSERT(bufferLength); - if (!bufferLength) - return; - - m_buffer.resize(bufferLength); - m_buffer.zero(); - - m_smoothingRate = AudioUtilities::discreteTimeConstantForSampleRate(SmoothingTimeConstant, sampleRate); -} - -void DelayDSPKernel::process(const float* source, float* destination, size_t framesToProcess) -{ - size_t bufferLength = m_buffer.size(); - float* buffer = m_buffer.data(); - - ASSERT(bufferLength); - if (!bufferLength) - return; - - ASSERT(source && destination); - if (!source || !destination) - return; - - double sampleRate = this->sampleRate(); - double delayTime = delayProcessor() ? delayProcessor()->delayTime()->value() : m_desiredDelayFrames / sampleRate; - - // Make sure the delay time is in a valid range. - delayTime = min(maxDelayTime(), delayTime); - delayTime = max(0.0, delayTime); - - if (m_firstTime) { - m_currentDelayTime = delayTime; - m_firstTime = false; - } - - int n = framesToProcess; - while (n--) { - // Approach desired delay time. - m_currentDelayTime += (delayTime - m_currentDelayTime) * m_smoothingRate; - - double desiredDelayFrames = m_currentDelayTime * sampleRate; - - double readPosition = m_writeIndex + bufferLength - desiredDelayFrames; - if (readPosition > bufferLength) - readPosition -= bufferLength; - - // Linearly interpolate in-between delay times. - int readIndex1 = static_cast(readPosition); - int readIndex2 = (readIndex1 + 1) % bufferLength; - double interpolationFactor = readPosition - readIndex1; - - double input = static_cast(*source++); - buffer[m_writeIndex] = static_cast(input); - m_writeIndex = (m_writeIndex + 1) % bufferLength; - - double sample1 = buffer[readIndex1]; - double sample2 = buffer[readIndex2]; - - double output = (1.0 - interpolationFactor) * sample1 + interpolationFactor * sample2; - - *destination++ = static_cast(output); - } -} - -void DelayDSPKernel::reset() -{ - m_firstTime = true; - m_buffer.zero(); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/DelayDSPKernel.h b/WebCore/webaudio/DelayDSPKernel.h deleted file mode 100644 index 2ae36cb..0000000 --- a/WebCore/webaudio/DelayDSPKernel.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2010, 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 DelayDSPKernel_h -#define DelayDSPKernel_h - -#include "AudioArray.h" -#include "AudioDSPKernel.h" -#include "DelayProcessor.h" - -namespace WebCore { - -class DelayProcessor; - -class DelayDSPKernel : public AudioDSPKernel { -public: - DelayDSPKernel(DelayProcessor*); - DelayDSPKernel(double maxDelayTime, double sampleRate); - - virtual void process(const float* source, float* destination, size_t framesToProcess); - virtual void reset(); - - double maxDelayTime() const { return m_maxDelayTime; } - - void setDelayFrames(double numberOfFrames) { m_desiredDelayFrames = numberOfFrames; } - -private: - AudioFloatArray m_buffer; - double m_maxDelayTime; - int m_writeIndex; - double m_currentDelayTime; - double m_smoothingRate; - bool m_firstTime; - double m_desiredDelayFrames; - - DelayProcessor* delayProcessor() { return static_cast(processor()); } -}; - -} // namespace WebCore - -#endif // DelayDSPKernel_h diff --git a/WebCore/webaudio/DelayNode.cpp b/WebCore/webaudio/DelayNode.cpp deleted file mode 100644 index 29fceae..0000000 --- a/WebCore/webaudio/DelayNode.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2010, 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 "DelayNode.h" - -namespace WebCore { - -DelayNode::DelayNode(AudioContext* context, double sampleRate) - : AudioBasicProcessorNode(context, sampleRate) -{ - m_processor = adoptPtr(new DelayProcessor(sampleRate, 1)); - setType(NodeTypeDelay); -} - -AudioParam* DelayNode::delayTime() -{ - return delayProcessor()->delayTime(); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/DelayNode.h b/WebCore/webaudio/DelayNode.h deleted file mode 100644 index 93ad227..0000000 --- a/WebCore/webaudio/DelayNode.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010, 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 DelayNode_h -#define DelayNode_h - -#include "AudioBasicProcessorNode.h" -#include "DelayProcessor.h" -#include - -namespace WebCore { - -class AudioParam; - -class DelayNode : public AudioBasicProcessorNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new DelayNode(context, sampleRate)); - } - - AudioParam* delayTime(); - -private: - DelayNode(AudioContext*, double sampleRate); - - DelayProcessor* delayProcessor() { return static_cast(processor()); } -}; - -} // namespace WebCore - -#endif // DelayNode_h diff --git a/WebCore/webaudio/DelayNode.idl b/WebCore/webaudio/DelayNode.idl deleted file mode 100644 index 7756627..0000000 --- a/WebCore/webaudio/DelayNode.idl +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] DelayNode : AudioNode { - readonly attribute AudioParam delayTime; - }; -} diff --git a/WebCore/webaudio/DelayProcessor.cpp b/WebCore/webaudio/DelayProcessor.cpp deleted file mode 100644 index 5fdc8df..0000000 --- a/WebCore/webaudio/DelayProcessor.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2010, 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 "DelayProcessor.h" - -#include "DelayDSPKernel.h" - -namespace WebCore { - -DelayProcessor::DelayProcessor(double sampleRate, unsigned numberOfChannels) - : AudioDSPKernelProcessor(sampleRate, numberOfChannels) -{ - m_delayTime = AudioParam::create("delayTime", 0.0, 0.0, 1.0); -} - -DelayProcessor::~DelayProcessor() -{ - if (isInitialized()) - uninitialize(); -} - -PassOwnPtr DelayProcessor::createKernel() -{ - return adoptPtr(new DelayDSPKernel(this)); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/DelayProcessor.h b/WebCore/webaudio/DelayProcessor.h deleted file mode 100644 index 4844c4b..0000000 --- a/WebCore/webaudio/DelayProcessor.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010, 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 DelayProcessor_h -#define DelayProcessor_h - -#include "AudioDSPKernelProcessor.h" -#include "AudioParam.h" - -#include -#include - -namespace WebCore { - -class AudioDSPKernel; - -class DelayProcessor : public AudioDSPKernelProcessor { -public: - DelayProcessor(double sampleRate, unsigned numberOfChannels); - virtual ~DelayProcessor(); - - virtual PassOwnPtr createKernel(); - - AudioParam* delayTime() const { return m_delayTime.get(); } - -private: - RefPtr m_delayTime; -}; - -} // namespace WebCore - -#endif // DelayProcessor_h diff --git a/WebCore/webaudio/HighPass2FilterNode.cpp b/WebCore/webaudio/HighPass2FilterNode.cpp deleted file mode 100644 index ca33784..0000000 --- a/WebCore/webaudio/HighPass2FilterNode.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010, 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 "HighPass2FilterNode.h" - -namespace WebCore { - -HighPass2FilterNode::HighPass2FilterNode(AudioContext* context, double sampleRate) - : AudioBasicProcessorNode(context, sampleRate) -{ - m_processor = adoptPtr(new BiquadProcessor(BiquadProcessor::HighPass2, sampleRate, 1, false)); - setType(NodeTypeHighPass2Filter); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/HighPass2FilterNode.h b/WebCore/webaudio/HighPass2FilterNode.h deleted file mode 100644 index be0beb6..0000000 --- a/WebCore/webaudio/HighPass2FilterNode.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010, 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 HighPass2FilterNode_h -#define HighPass2FilterNode_h - -#include "AudioBasicProcessorNode.h" -#include "BiquadProcessor.h" - -namespace WebCore { - -class AudioParam; - -class HighPass2FilterNode : public AudioBasicProcessorNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new HighPass2FilterNode(context, sampleRate)); - } - - AudioParam* cutoff() { return biquadProcessor()->parameter1(); } - AudioParam* resonance() { return biquadProcessor()->parameter2(); } - -private: - HighPass2FilterNode(AudioContext*, double sampleRate); - - BiquadProcessor* biquadProcessor() { return static_cast(processor()); } -}; - -} // namespace WebCore - -#endif // HighPass2FilterNode_h diff --git a/WebCore/webaudio/HighPass2FilterNode.idl b/WebCore/webaudio/HighPass2FilterNode.idl deleted file mode 100644 index 399f9b5..0000000 --- a/WebCore/webaudio/HighPass2FilterNode.idl +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - // Two-pole highpass filter - // FIXME: design BiquadNode and use instead of this - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] HighPass2FilterNode : AudioNode { - readonly attribute AudioParam cutoff; - readonly attribute AudioParam resonance; - }; -} diff --git a/WebCore/webaudio/JavaScriptAudioNode.cpp b/WebCore/webaudio/JavaScriptAudioNode.cpp deleted file mode 100644 index 15a8cf7..0000000 --- a/WebCore/webaudio/JavaScriptAudioNode.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2010, 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 "JavaScriptAudioNode.h" - -#include "AudioBuffer.h" -#include "AudioBus.h" -#include "AudioContext.h" -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" -#include "AudioProcessingEvent.h" -#include "Document.h" -#include "Float32Array.h" -#include - -namespace WebCore { - -const size_t DefaultBufferSize = 4096; - -PassRefPtr JavaScriptAudioNode::create(AudioContext* context, double sampleRate, size_t bufferSize, unsigned numberOfInputs, unsigned numberOfOutputs) -{ - return adoptRef(new JavaScriptAudioNode(context, sampleRate, bufferSize, numberOfInputs, numberOfOutputs)); -} - -JavaScriptAudioNode::JavaScriptAudioNode(AudioContext* context, double sampleRate, size_t bufferSize, unsigned numberOfInputs, unsigned numberOfOutputs) - : AudioNode(context, sampleRate) - , m_doubleBufferIndex(0) - , m_doubleBufferIndexForEvent(0) - , m_bufferSize(bufferSize) - , m_bufferReadWriteIndex(0) - , m_isRequestOutstanding(false) -{ - // Check for valid buffer size. - switch (bufferSize) { - case 256: - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - m_bufferSize = bufferSize; - break; - default: - m_bufferSize = DefaultBufferSize; - } - - // Regardless of the allowed buffer sizes above, we still need to process at the granularity of the AudioNode. - if (m_bufferSize < AudioNode::ProcessingSizeInFrames) - m_bufferSize = AudioNode::ProcessingSizeInFrames; - - // FIXME: Right now we're hardcoded to single input and single output. - // Although the specification says this is OK for a simple implementation, multiple inputs and outputs would be good. - ASSERT_UNUSED(numberOfInputs, numberOfInputs == 1); - ASSERT_UNUSED(numberOfOutputs, numberOfOutputs == 1); - addInput(adoptPtr(new AudioNodeInput(this))); - addOutput(adoptPtr(new AudioNodeOutput(this, 2))); - - setType(NodeTypeJavaScript); - - initialize(); -} - -JavaScriptAudioNode::~JavaScriptAudioNode() -{ - uninitialize(); -} - -void JavaScriptAudioNode::initialize() -{ - if (isInitialized()) - return; - - double sampleRate = context()->sampleRate(); - - // Create double buffers on both the input and output sides. - // These AudioBuffers will be directly accessed in the main thread by JavaScript. - for (unsigned i = 0; i < 2; ++i) { - m_inputBuffers.append(AudioBuffer::create(2, bufferSize(), sampleRate)); - m_outputBuffers.append(AudioBuffer::create(2, bufferSize(), sampleRate)); - } - - AudioNode::initialize(); -} - -void JavaScriptAudioNode::uninitialize() -{ - if (!isInitialized()) - return; - - m_inputBuffers.clear(); - m_outputBuffers.clear(); - - AudioNode::uninitialize(); -} - -JavaScriptAudioNode* JavaScriptAudioNode::toJavaScriptAudioNode() -{ - return this; -} - -void JavaScriptAudioNode::process(size_t framesToProcess) -{ - // Discussion about inputs and outputs: - // As in other AudioNodes, JavaScriptAudioNode uses an AudioBus for its input and output (see inputBus and outputBus below). - // Additionally, there is a double-buffering for input and output which is exposed directly to JavaScript (see inputBuffer and outputBuffer below). - // This node is the producer for inputBuffer and the consumer for outputBuffer. - // The JavaScript code is the consumer of inputBuffer and the producer for outputBuffer. - - // Get input and output busses. - AudioBus* inputBus = this->input(0)->bus(); - AudioBus* outputBus = this->output(0)->bus(); - - // Get input and output buffers. We double-buffer both the input and output sides. - unsigned doubleBufferIndex = this->doubleBufferIndex(); - bool isDoubleBufferIndexGood = doubleBufferIndex < 2 && doubleBufferIndex < m_inputBuffers.size() && doubleBufferIndex < m_outputBuffers.size(); - ASSERT(isDoubleBufferIndexGood); - if (!isDoubleBufferIndexGood) - return; - - AudioBuffer* inputBuffer = m_inputBuffers[doubleBufferIndex].get(); - AudioBuffer* outputBuffer = m_outputBuffers[doubleBufferIndex].get(); - - // Check the consistency of input and output buffers. - bool buffersAreGood = inputBuffer && outputBuffer && bufferSize() == inputBuffer->length() && bufferSize() == outputBuffer->length() - && m_bufferReadWriteIndex + framesToProcess <= bufferSize(); - ASSERT(buffersAreGood); - if (!buffersAreGood) - return; - - // We assume that bufferSize() is evenly divisible by framesToProcess - should always be true, but we should still check. - bool isFramesToProcessGood = framesToProcess && bufferSize() >= framesToProcess && !(bufferSize() % framesToProcess); - ASSERT(isFramesToProcessGood); - if (!isFramesToProcessGood) - return; - - unsigned numberOfInputChannels = inputBus->numberOfChannels(); - - bool channelsAreGood = (numberOfInputChannels == 1 || numberOfInputChannels == 2) && outputBus->numberOfChannels() == 2; - ASSERT(channelsAreGood); - if (!channelsAreGood) - return; - - float* sourceL = inputBus->channel(0)->data(); - float* sourceR = numberOfInputChannels > 1 ? inputBus->channel(1)->data() : 0; - float* destinationL = outputBus->channel(0)->data(); - float* destinationR = outputBus->channel(1)->data(); - - // Copy from the input to the input buffer. See "buffersAreGood" check above for safety. - size_t bytesToCopy = sizeof(float) * framesToProcess; - memcpy(inputBuffer->getChannelData(0)->data() + m_bufferReadWriteIndex, sourceL, bytesToCopy); - - if (numberOfInputChannels == 2) - memcpy(inputBuffer->getChannelData(1)->data() + m_bufferReadWriteIndex, sourceR, bytesToCopy); - else if (numberOfInputChannels == 1) { - // If the input is mono, then also copy the mono input to the right channel of the AudioBuffer which the AudioProcessingEvent uses. - // FIXME: it is likely the audio API will evolve to present an AudioBuffer with the same number of channels as our input. - memcpy(inputBuffer->getChannelData(1)->data() + m_bufferReadWriteIndex, sourceL, bytesToCopy); - } - - // Copy from the output buffer to the output. See "buffersAreGood" check above for safety. - memcpy(destinationL, outputBuffer->getChannelData(0)->data() + m_bufferReadWriteIndex, bytesToCopy); - memcpy(destinationR, outputBuffer->getChannelData(1)->data() + m_bufferReadWriteIndex, bytesToCopy); - - // Update the buffering index. - m_bufferReadWriteIndex = (m_bufferReadWriteIndex + framesToProcess) % bufferSize(); - - // m_bufferReadWriteIndex will wrap back around to 0 when the current input and output buffers are full. - // When this happens, fire an event and swap buffers. - if (!m_bufferReadWriteIndex) { - // Avoid building up requests on the main thread to fire process events when they're not being handled. - // This could be a problem if the main thread is very busy doing other things and is being held up handling previous requests. - if (m_isRequestOutstanding) { - // We're late in handling the previous request. The main thread must be very busy. - // The best we can do is clear out the buffer ourself here. - outputBuffer->zero(); - } else { - // Reference ourself so we don't accidentally get deleted before fireProcessEvent() gets called. - ref(); - - // Fire the event on the main thread, not this one (which is the realtime audio thread). - m_doubleBufferIndexForEvent = m_doubleBufferIndex; - callOnMainThread(fireProcessEventDispatch, this); - m_isRequestOutstanding = true; - } - - swapBuffers(); - } -} - -void JavaScriptAudioNode::fireProcessEventDispatch(void* userData) -{ - JavaScriptAudioNode* jsAudioNode = static_cast(userData); - ASSERT(jsAudioNode); - if (!jsAudioNode) - return; - - jsAudioNode->fireProcessEvent(); - - // De-reference to match the ref() call in process(). - jsAudioNode->deref(); -} - -void JavaScriptAudioNode::fireProcessEvent() -{ - ASSERT(isMainThread() && m_isRequestOutstanding); - - bool isIndexGood = m_doubleBufferIndexForEvent < 2; - ASSERT(isIndexGood); - if (!isIndexGood) - return; - - AudioBuffer* inputBuffer = m_inputBuffers[m_doubleBufferIndexForEvent].get(); - AudioBuffer* outputBuffer = m_outputBuffers[m_doubleBufferIndexForEvent].get(); - ASSERT(inputBuffer && outputBuffer); - if (!inputBuffer || !outputBuffer) - return; - - // Avoid firing the event if the document has already gone away. - if (context()->hasDocument()) { - // Let the audio thread know we've gotten to the point where it's OK for it to make another request. - m_isRequestOutstanding = false; - - // Call the JavaScript event handler which will do the audio processing. - dispatchEvent(AudioProcessingEvent::create(inputBuffer, outputBuffer)); - } -} - -void JavaScriptAudioNode::reset() -{ - m_bufferReadWriteIndex = 0; - m_doubleBufferIndex = 0; - - for (unsigned i = 0; i < 2; ++i) { - m_inputBuffers[i]->zero(); - m_outputBuffers[i]->zero(); - } -} - -ScriptExecutionContext* JavaScriptAudioNode::scriptExecutionContext() const -{ - return const_cast(this)->context()->document(); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/JavaScriptAudioNode.h b/WebCore/webaudio/JavaScriptAudioNode.h deleted file mode 100644 index e99a25d..0000000 --- a/WebCore/webaudio/JavaScriptAudioNode.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2010, 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 JavaScriptAudioNode_h -#define JavaScriptAudioNode_h - -#include "ActiveDOMObject.h" -#include "AudioNode.h" -#include "EventListener.h" -#include "EventTarget.h" -#include -#include -#include - -namespace WebCore { - -class AudioBuffer; -class AudioContext; -class AudioProcessingEvent; -class Float32Array; - -// JavaScriptAudioNode is an AudioNode which allows for arbitrary synthesis or processing directly using JavaScript. -// The API allows for a variable number of inputs and outputs, although it must have at least one input or output. -// This basic implementation supports no more than one input and output. -// The "onaudioprocess" attribute is an event listener which will get called periodically with an AudioProcessingEvent which has -// AudioBuffers for each input and output. - -class JavaScriptAudioNode : public AudioNode, public EventTarget { -public: - // bufferSize must be one of the following values: 256, 512, 1024, 2048, 4096, 8192, 16384. - // This value controls how frequently the onaudioprocess event handler is called and how many sample-frames need to be processed each call. - // Lower numbers for bufferSize will result in a lower (better) latency. Higher numbers will be necessary to avoid audio breakup and glitches. - // The value chosen must carefully balance between latency and audio quality. - static PassRefPtr create(AudioContext*, double sampleRate, size_t bufferSize, unsigned numberOfInputs = 1, unsigned numberOfOutputs = 1); - - virtual ~JavaScriptAudioNode(); - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void reset(); - virtual void initialize(); - virtual void uninitialize(); - - // EventTarget - virtual ScriptExecutionContext* scriptExecutionContext() const; - virtual JavaScriptAudioNode* toJavaScriptAudioNode(); - virtual EventTargetData* eventTargetData() { return &m_eventTargetData; } - virtual EventTargetData* ensureEventTargetData() { return &m_eventTargetData; } - - size_t bufferSize() const { return m_bufferSize; } - - DEFINE_ATTRIBUTE_EVENT_LISTENER(audioprocess); - - // Reconcile ref/deref which are defined both in AudioNode and EventTarget. - using AudioNode::ref; - using AudioNode::deref; - -private: - JavaScriptAudioNode(AudioContext*, double sampleRate, size_t bufferSize, unsigned numberOfInputs, unsigned numberOfOutputs); - - static void fireProcessEventDispatch(void* userData); - void fireProcessEvent(); - - // Double buffering - unsigned doubleBufferIndex() const { return m_doubleBufferIndex; } - void swapBuffers() { m_doubleBufferIndex = 1 - m_doubleBufferIndex; } - unsigned m_doubleBufferIndex; - unsigned m_doubleBufferIndexForEvent; - Vector > m_inputBuffers; - Vector > m_outputBuffers; - - virtual void refEventTarget() { ref(); } - virtual void derefEventTarget() { deref(); } - EventTargetData m_eventTargetData; - - size_t m_bufferSize; - unsigned m_bufferReadWriteIndex; - volatile bool m_isRequestOutstanding; -}; - -} // namespace WebCore - -#endif // JavaScriptAudioNode_h diff --git a/WebCore/webaudio/JavaScriptAudioNode.idl b/WebCore/webaudio/JavaScriptAudioNode.idl deleted file mode 100644 index ef5359b..0000000 --- a/WebCore/webaudio/JavaScriptAudioNode.idl +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - // For real-time audio stream synthesis/processing in JavaScript - interface [ - Conditional=WEB_AUDIO, - GenerateToJS, - CustomMarkFunction, -#if defined(V8_BINDING) && V8_BINDING - EventTarget -#endif - ] JavaScriptAudioNode : AudioNode { - // Rendering callback - attribute EventListener onaudioprocess; - - readonly attribute long bufferSize; - }; -} diff --git a/WebCore/webaudio/LowPass2FilterNode.cpp b/WebCore/webaudio/LowPass2FilterNode.cpp deleted file mode 100644 index 691f4ed..0000000 --- a/WebCore/webaudio/LowPass2FilterNode.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010, 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 "LowPass2FilterNode.h" - -namespace WebCore { - -LowPass2FilterNode::LowPass2FilterNode(AudioContext* context, double sampleRate) - : AudioBasicProcessorNode(context, sampleRate) -{ - m_processor = adoptPtr(new BiquadProcessor(BiquadProcessor::LowPass2, sampleRate, 1, false)); - setType(NodeTypeLowPass2Filter); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/LowPass2FilterNode.h b/WebCore/webaudio/LowPass2FilterNode.h deleted file mode 100644 index 43d7051..0000000 --- a/WebCore/webaudio/LowPass2FilterNode.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010, 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 LowPass2FilterNode_h -#define LowPass2FilterNode_h - -#include "AudioBasicProcessorNode.h" -#include "BiquadProcessor.h" - -namespace WebCore { - -class AudioParam; - -class LowPass2FilterNode : public AudioBasicProcessorNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new LowPass2FilterNode(context, sampleRate)); - } - - AudioParam* cutoff() { return biquadProcessor()->parameter1(); } - AudioParam* resonance() { return biquadProcessor()->parameter2(); } - -private: - LowPass2FilterNode(AudioContext*, double sampleRate); - - BiquadProcessor* biquadProcessor() { return static_cast(processor()); } -}; - -} // namespace WebCore - -#endif // LowPass2FilterNode_h diff --git a/WebCore/webaudio/LowPass2FilterNode.idl b/WebCore/webaudio/LowPass2FilterNode.idl deleted file mode 100644 index 310c21e..0000000 --- a/WebCore/webaudio/LowPass2FilterNode.idl +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - // Two-pole lowpass filter - // FIXME: design BiquadNode and use instead of this - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] LowPass2FilterNode : AudioNode { - readonly attribute AudioParam cutoff; - readonly attribute AudioParam resonance; - }; -} diff --git a/WebCore/webaudio/RealtimeAnalyser.cpp b/WebCore/webaudio/RealtimeAnalyser.cpp deleted file mode 100644 index 30a7de1..0000000 --- a/WebCore/webaudio/RealtimeAnalyser.cpp +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 2010, 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 "RealtimeAnalyser.h" - -#include "AudioBus.h" -#include "AudioUtilities.h" -#include "FFTFrame.h" - -#if ENABLE(3D_CANVAS) -#include "Float32Array.h" -#include "Uint8Array.h" -#endif - -#include -#include -#include -#include -#include - -using namespace std; - -namespace WebCore { - -const double RealtimeAnalyser::DefaultSmoothingTimeConstant = 0.8; -const double RealtimeAnalyser::DefaultMinDecibels = -100.0; -const double RealtimeAnalyser::DefaultMaxDecibels = -30.0; - -const unsigned RealtimeAnalyser::DefaultFFTSize = 2048; -const unsigned RealtimeAnalyser::MaxFFTSize = 2048; -const unsigned RealtimeAnalyser::InputBufferSize = RealtimeAnalyser::MaxFFTSize * 2; - -RealtimeAnalyser::RealtimeAnalyser() - : m_inputBuffer(InputBufferSize) - , m_writeIndex(0) - , m_fftSize(DefaultFFTSize) - , m_magnitudeBuffer(DefaultFFTSize / 2) - , m_smoothingTimeConstant(DefaultSmoothingTimeConstant) - , m_minDecibels(DefaultMinDecibels) - , m_maxDecibels(DefaultMaxDecibels) -{ - m_analysisFrame = adoptPtr(new FFTFrame(DefaultFFTSize)); -} - -RealtimeAnalyser::~RealtimeAnalyser() -{ -} - -void RealtimeAnalyser::reset() -{ - m_writeIndex = 0; - m_inputBuffer.zero(); - m_magnitudeBuffer.zero(); -} - -void RealtimeAnalyser::setFftSize(size_t size) -{ - ASSERT(isMainThread()); - - // Only allow powers of two. - unsigned log2size = static_cast(log2(size)); - bool isPOT(1UL << log2size == size); - - if (!isPOT || size > MaxFFTSize) { - // FIXME: It would be good to also set an exception. - return; - } - - if (m_fftSize != size) { - m_analysisFrame = adoptPtr(new FFTFrame(m_fftSize)); - m_magnitudeBuffer.resize(size); - m_fftSize = size; - } -} - -void RealtimeAnalyser::writeInput(AudioBus* bus, size_t framesToProcess) -{ - bool isBusGood = bus && bus->numberOfChannels() > 0 && bus->channel(0)->length() >= framesToProcess; - ASSERT(isBusGood); - if (!isBusGood) - return; - - // FIXME : allow to work with non-FFTSize divisible chunking - bool isDestinationGood = m_writeIndex < m_inputBuffer.size() && m_writeIndex + framesToProcess <= m_inputBuffer.size(); - ASSERT(isDestinationGood); - if (!isDestinationGood) - return; - - // Perform real-time analysis - // FIXME : for now just use left channel (must mix if stereo source) - float* source = bus->channel(0)->data(); - - // The source has already been sanity checked with isBusGood above. - - memcpy(m_inputBuffer.data() + m_writeIndex, source, sizeof(float) * framesToProcess); - - m_writeIndex += framesToProcess; - if (m_writeIndex >= InputBufferSize) - m_writeIndex = 0; -} - -namespace { - -void applyWindow(float* p, size_t n) -{ - ASSERT(isMainThread()); - - // Blackman window - double alpha = 0.16; - double a0 = 0.5 * (1.0 - alpha); - double a1 = 0.5; - double a2 = 0.5 * alpha; - - for (unsigned i = 0; i < n; ++i) { - double x = static_cast(i) / static_cast(n); - double window = a0 - a1 * cos(2.0 * piDouble * x) + a2 * cos(4.0 * piDouble * x); - p[i] *= float(window); - } -} - -} // namespace - -void RealtimeAnalyser::doFFTAnalysis() -{ - ASSERT(isMainThread()); - - // Unroll the input buffer into a temporary buffer, where we'll apply an analysis window followed by an FFT. - size_t fftSize = this->fftSize(); - - AudioFloatArray temporaryBuffer(fftSize); - float* inputBuffer = m_inputBuffer.data(); - float* tempP = temporaryBuffer.data(); - - // Take the previous fftSize values from the input buffer and copy into the temporary buffer. - // FIXME : optimize with memcpy(). - unsigned writeIndex = m_writeIndex; - for (unsigned i = 0; i < fftSize; ++i) - tempP[i] = inputBuffer[(i + writeIndex - fftSize + InputBufferSize) % InputBufferSize]; - - // Window the input samples. - applyWindow(tempP, fftSize); - - // Do the analysis. - m_analysisFrame->doFFT(tempP); - - size_t n = DefaultFFTSize / 2; - - float* realP = m_analysisFrame->realData(); - float* imagP = m_analysisFrame->imagData(); - - // Blow away the packed nyquist component. - imagP[0] = 0.0f; - - // Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT scaling factor). - const double MagnitudeScale = 1.0 / DefaultFFTSize; - - // A value of 0 does no averaging with the previous result. Larger values produce slower, but smoother changes. - double k = m_smoothingTimeConstant; - k = max(0.0, k); - k = min(1.0, k); - - // Convert the analysis data from complex to magnitude and average with the previous result. - float* destination = magnitudeBuffer().data(); - for (unsigned i = 0; i < n; ++i) { - Complex c(realP[i], imagP[i]); - double scalarMagnitude = abs(c) * MagnitudeScale; - destination[i] = float(k * destination[i] + (1.0 - k) * scalarMagnitude); - } -} - -#if ENABLE(3D_CANVAS) - -void RealtimeAnalyser::getFloatFrequencyData(Float32Array* destinationArray) -{ - ASSERT(isMainThread()); - - if (!destinationArray) - return; - - doFFTAnalysis(); - - // Convert from linear magnitude to floating-point decibels. - const double MinDecibels = m_minDecibels; - unsigned sourceLength = magnitudeBuffer().size(); - size_t len = min(sourceLength, destinationArray->length()); - if (len > 0) { - const float* source = magnitudeBuffer().data(); - float* destination = destinationArray->data(); - - for (unsigned i = 0; i < len; ++i) { - float linearValue = source[i]; - double dbMag = !linearValue ? MinDecibels : AudioUtilities::linearToDecibels(linearValue); - destination[i] = float(dbMag); - } - } -} - -void RealtimeAnalyser::getByteFrequencyData(Uint8Array* destinationArray) -{ - ASSERT(isMainThread()); - - if (!destinationArray) - return; - - doFFTAnalysis(); - - // Convert from linear magnitude to unsigned-byte decibels. - unsigned sourceLength = magnitudeBuffer().size(); - size_t len = min(sourceLength, destinationArray->length()); - if (len > 0) { - const double RangeScaleFactor = m_maxDecibels == m_minDecibels ? 1.0 : 1.0 / (m_maxDecibels - m_minDecibels); - - const float* source = magnitudeBuffer().data(); - unsigned char* destination = destinationArray->data(); - - for (unsigned i = 0; i < len; ++i) { - float linearValue = source[i]; - double dbMag = !linearValue ? m_minDecibels : AudioUtilities::linearToDecibels(linearValue); - - // The range m_minDecibels to m_maxDecibels will be scaled to byte values from 0 to UCHAR_MAX. - double scaledValue = UCHAR_MAX * (dbMag - m_minDecibels) * RangeScaleFactor; - - // Clip to valid range. - if (scaledValue < 0.0) - scaledValue = 0.0; - if (scaledValue > UCHAR_MAX) - scaledValue = UCHAR_MAX; - - destination[i] = static_cast(scaledValue); - } - } -} - -void RealtimeAnalyser::getByteTimeDomainData(Uint8Array* destinationArray) -{ - ASSERT(isMainThread()); - - if (!destinationArray) - return; - - unsigned fftSize = this->fftSize(); - size_t len = min(fftSize, destinationArray->length()); - if (len > 0) { - bool isInputBufferGood = m_inputBuffer.size() == InputBufferSize && m_inputBuffer.size() > fftSize; - ASSERT(isInputBufferGood); - if (!isInputBufferGood) - return; - - float* inputBuffer = m_inputBuffer.data(); - unsigned char* destination = destinationArray->data(); - - unsigned writeIndex = m_writeIndex; - - for (unsigned i = 0; i < len; ++i) { - // Buffer access is protected due to modulo operation. - float value = inputBuffer[(i + writeIndex - fftSize + InputBufferSize) % InputBufferSize]; - - // Scale from nominal -1.0 -> +1.0 to unsigned byte. - double scaledValue = 128.0 * (value + 1.0); - - // Clip to valid range. - if (scaledValue < 0.0) - scaledValue = 0.0; - if (scaledValue > UCHAR_MAX) - scaledValue = UCHAR_MAX; - - destination[i] = static_cast(scaledValue); - } - } -} - -#endif // 3D_CANVAS - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/RealtimeAnalyser.h b/WebCore/webaudio/RealtimeAnalyser.h deleted file mode 100644 index 686c17c..0000000 --- a/WebCore/webaudio/RealtimeAnalyser.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010, 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 RealtimeAnalyser_h -#define RealtimeAnalyser_h - -#include "AudioArray.h" -#include -#include - -namespace WebCore { - -class AudioBus; -class FFTFrame; - -#if ENABLE(3D_CANVAS) -class Float32Array; -class Uint8Array; -#endif - -class RealtimeAnalyser : public Noncopyable { -public: - RealtimeAnalyser(); - virtual ~RealtimeAnalyser(); - - void reset(); - - size_t fftSize() const { return m_fftSize; } - void setFftSize(size_t size); - - unsigned frequencyBinCount() const { return m_fftSize / 2; } - - void setMinDecibels(float k) { m_minDecibels = k; } - float minDecibels() const { return static_cast(m_minDecibels); } - - void setMaxDecibels(float k) { m_maxDecibels = k; } - float maxDecibels() const { return static_cast(m_maxDecibels); } - - void setSmoothingTimeConstant(float k) { m_smoothingTimeConstant = k; } - float smoothingTimeConstant() const { return static_cast(m_smoothingTimeConstant); } - -#if ENABLE(3D_CANVAS) - void getFloatFrequencyData(Float32Array*); - void getByteFrequencyData(Uint8Array*); - void getByteTimeDomainData(Uint8Array*); -#endif - - // The audio thread writes input data here. - void writeInput(AudioBus*, size_t framesToProcess); - - static const double DefaultSmoothingTimeConstant; - static const double DefaultMinDecibels; - static const double DefaultMaxDecibels; - - static const unsigned DefaultFFTSize; - static const unsigned MaxFFTSize; - static const unsigned InputBufferSize; - -private: - // The audio thread writes the input audio here. - AudioFloatArray m_inputBuffer; - unsigned m_writeIndex; - - size_t m_fftSize; - OwnPtr m_analysisFrame; - void doFFTAnalysis(); - - // doFFTAnalysis() stores the floating-point magnitude analysis data here. - AudioFloatArray m_magnitudeBuffer; - AudioFloatArray& magnitudeBuffer() { return m_magnitudeBuffer; } - - // A value between 0 and 1 which averages the previous version of m_magnitudeBuffer with the current analysis magnitude data. - double m_smoothingTimeConstant; - - // The range used when converting when using getByteFrequencyData(). - double m_minDecibels; - double m_maxDecibels; -}; - -} // namespace WebCore - -#endif // RealtimeAnalyser_h diff --git a/WebCore/webaudio/RealtimeAnalyserNode.cpp b/WebCore/webaudio/RealtimeAnalyserNode.cpp deleted file mode 100644 index 2ba751a..0000000 --- a/WebCore/webaudio/RealtimeAnalyserNode.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2010, 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 "RealtimeAnalyserNode.h" - -#include "AudioNodeInput.h" -#include "AudioNodeOutput.h" - -namespace WebCore { - -RealtimeAnalyserNode::RealtimeAnalyserNode(AudioContext* context, double sampleRate) - : AudioNode(context, sampleRate) -{ - addInput(adoptPtr(new AudioNodeInput(this))); - addOutput(adoptPtr(new AudioNodeOutput(this, 2))); - - setType(NodeTypeAnalyser); - - initialize(); -} - -RealtimeAnalyserNode::~RealtimeAnalyserNode() -{ - uninitialize(); -} - -void RealtimeAnalyserNode::process(size_t framesToProcess) -{ - AudioBus* outputBus = output(0)->bus(); - - if (!isInitialized() || !input(0)->isConnected()) { - outputBus->zero(); - return; - } - - AudioBus* inputBus = input(0)->bus(); - - // Give the analyser the audio which is passing through this AudioNode. - m_analyser.writeInput(inputBus, framesToProcess); - - // For in-place processing, our override of pullInputs() will just pass the audio data through unchanged if the channel count matches from input to output - // (resulting in inputBus == outputBus). Otherwise, do an up-mix to stereo. - if (inputBus != outputBus) - outputBus->copyFrom(*inputBus); -} - -// We override pullInputs() as an optimization allowing this node to take advantage of in-place processing, -// where the input is simply passed through unprocessed to the output. -// Note: this only applies if the input and output channel counts match. -void RealtimeAnalyserNode::pullInputs(size_t framesToProcess) -{ - // Render input stream - try to render directly into output bus for pass-through processing where process() doesn't need to do anything... - input(0)->pull(output(0)->bus(), framesToProcess); -} - -void RealtimeAnalyserNode::reset() -{ - m_analyser.reset(); -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) diff --git a/WebCore/webaudio/RealtimeAnalyserNode.h b/WebCore/webaudio/RealtimeAnalyserNode.h deleted file mode 100644 index 9f62464..0000000 --- a/WebCore/webaudio/RealtimeAnalyserNode.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2010, 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 RealtimeAnalyserNode_h -#define RealtimeAnalyserNode_h - -#include "AudioNode.h" -#include "RealtimeAnalyser.h" - -namespace WebCore { - -class RealtimeAnalyserNode : public AudioNode { -public: - static PassRefPtr create(AudioContext* context, double sampleRate) - { - return adoptRef(new RealtimeAnalyserNode(context, sampleRate)); - } - - virtual ~RealtimeAnalyserNode(); - - // AudioNode - virtual void process(size_t framesToProcess); - virtual void pullInputs(size_t framesToProcess); - virtual void reset(); - - // Javascript bindings - unsigned int fftSize() const { return m_analyser.fftSize(); } - void setFftSize(unsigned int size) { m_analyser.setFftSize(size); } - - unsigned frequencyBinCount() const { return m_analyser.frequencyBinCount(); } - - void setMinDecibels(float k) { m_analyser.setMinDecibels(k); } - float minDecibels() const { return m_analyser.minDecibels(); } - - void setMaxDecibels(float k) { m_analyser.setMaxDecibels(k); } - float maxDecibels() const { return m_analyser.maxDecibels(); } - - void setSmoothingTimeConstant(float k) { m_analyser.setSmoothingTimeConstant(k); } - float smoothingTimeConstant() const { return m_analyser.smoothingTimeConstant(); } - -#if ENABLE(3D_CANVAS) - void getFloatFrequencyData(Float32Array* array) { m_analyser.getFloatFrequencyData(array); } - void getByteFrequencyData(Uint8Array* array) { m_analyser.getByteFrequencyData(array); } - void getByteTimeDomainData(Uint8Array* array) { m_analyser.getByteTimeDomainData(array); } -#endif - -private: - RealtimeAnalyserNode(AudioContext*, double sampleRate); - - RealtimeAnalyser m_analyser; -}; - -} // namespace WebCore - -#endif // RealtimeAnalyserNode_h diff --git a/WebCore/webaudio/RealtimeAnalyserNode.idl b/WebCore/webaudio/RealtimeAnalyserNode.idl deleted file mode 100644 index 5b2b223..0000000 --- a/WebCore/webaudio/RealtimeAnalyserNode.idl +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010, 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. - */ - -module audio { - interface [ - Conditional=WEB_AUDIO, - GenerateToJS - ] RealtimeAnalyserNode : AudioNode { - attribute unsigned long fftSize; - readonly attribute unsigned long frequencyBinCount; - - // minDecibels / maxDecibels represent the range to scale the FFT analysis data for conversion to unsigned byte values. - attribute float minDecibels; - attribute float maxDecibels; - - // A value from 0.0 -> 1.0 where 0.0 represents no time averaging with the last analysis frame. - attribute float smoothingTimeConstant; - - // Copies the current frequency data into the passed array. - // If the array has fewer elements than the frequencyBinCount, the excess elements will be dropped. - [Conditional=3D_CANVAS] void getFloatFrequencyData(in Float32Array array); - [Conditional=3D_CANVAS] void getByteFrequencyData(in Uint8Array array); - - // Real-time waveform data - [Conditional=3D_CANVAS] void getByteTimeDomainData(in Uint8Array array); - }; -} -- cgit v1.1