From a650589661fb24321909ffb04c3d06511e2884bd Mon Sep 17 00:00:00 2001 From: "crogers@google.com" Date: Fri, 3 Jun 2011 23:03:04 +0000 Subject: [PATCH] 2011-06-03 Chris Rogers Reviewed by Kenneth Russell. Allow existing AudioParams to use scheduled parameter changes https://bugs.webkit.org/show_bug.cgi?id=62046 No new tests since audio API is not yet implemented. * platform/audio/AudioBus.cpp: (WebCore::AudioBus::processWithGainFrom): (WebCore::AudioBus::copyWithSampleAccurateGainValuesFrom): * platform/audio/AudioBus.h: * webaudio/AudioBufferSourceNode.cpp: (WebCore::AudioBufferSourceNode::AudioBufferSourceNode): * webaudio/AudioGainNode.cpp: (WebCore::AudioGainNode::AudioGainNode): (WebCore::AudioGainNode::process): * webaudio/AudioGainNode.h: * webaudio/HighPass2FilterNode.cpp: (WebCore::HighPass2FilterNode::HighPass2FilterNode): * webaudio/LowPass2FilterNode.cpp: (WebCore::LowPass2FilterNode::LowPass2FilterNode): git-svn-id: https://svn.webkit.org/repository/webkit/trunk@88074 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebCore/ChangeLog | 24 +++++++++++++++ Source/WebCore/platform/audio/AudioBus.cpp | 30 ++++++++++++++++++- Source/WebCore/platform/audio/AudioBus.h | 3 ++ .../webaudio/AudioBufferSourceNode.cpp | 3 ++ Source/WebCore/webaudio/AudioGainNode.cpp | 20 ++++++++++--- Source/WebCore/webaudio/AudioGainNode.h | 2 ++ .../WebCore/webaudio/HighPass2FilterNode.cpp | 3 ++ .../WebCore/webaudio/LowPass2FilterNode.cpp | 3 ++ 8 files changed, 83 insertions(+), 5 deletions(-) diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 857ee4cbbaa6..2e8fa687dbe4 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,27 @@ +2011-06-03 Chris Rogers + + Reviewed by Kenneth Russell. + + Allow existing AudioParams to use scheduled parameter changes + https://bugs.webkit.org/show_bug.cgi?id=62046 + + No new tests since audio API is not yet implemented. + + * platform/audio/AudioBus.cpp: + (WebCore::AudioBus::processWithGainFrom): + (WebCore::AudioBus::copyWithSampleAccurateGainValuesFrom): + * platform/audio/AudioBus.h: + * webaudio/AudioBufferSourceNode.cpp: + (WebCore::AudioBufferSourceNode::AudioBufferSourceNode): + * webaudio/AudioGainNode.cpp: + (WebCore::AudioGainNode::AudioGainNode): + (WebCore::AudioGainNode::process): + * webaudio/AudioGainNode.h: + * webaudio/HighPass2FilterNode.cpp: + (WebCore::HighPass2FilterNode::HighPass2FilterNode): + * webaudio/LowPass2FilterNode.cpp: + (WebCore::LowPass2FilterNode::LowPass2FilterNode): + 2011-06-03 Chris Rogers Reviewed by Kenneth Russell. diff --git a/Source/WebCore/platform/audio/AudioBus.cpp b/Source/WebCore/platform/audio/AudioBus.cpp index 36a5e633ea07..e34f7dbd5e70 100644 --- a/Source/WebCore/platform/audio/AudioBus.cpp +++ b/Source/WebCore/platform/audio/AudioBus.cpp @@ -336,8 +336,10 @@ void AudioBus::processWithGainFrom(const AudioBus &sourceBus, double* lastMixGai { // Make sure we're summing from same type of bus. // We *are* able to sum from mono -> stereo - if (sourceBus.numberOfChannels() != 1 && !topologyMatches(sourceBus)) + if (sourceBus.numberOfChannels() != 1 && !topologyMatches(sourceBus)) { + ASSERT_NOT_REACHED(); return; + } // Dispatch for different channel layouts switch (numberOfChannels()) { @@ -353,6 +355,32 @@ void AudioBus::processWithGainFrom(const AudioBus &sourceBus, double* lastMixGai } } +void AudioBus::copyWithSampleAccurateGainValuesFrom(const AudioBus &sourceBus, float* gainValues, unsigned numberOfGainValues) +{ + // Make sure we're processing from the same type of bus. + // We *are* able to process from mono -> stereo + if (sourceBus.numberOfChannels() != 1 && !topologyMatches(sourceBus)) { + ASSERT_NOT_REACHED(); + return; + } + + if (!gainValues || numberOfGainValues > sourceBus.length()) { + ASSERT_NOT_REACHED(); + return; + } + + // FIXME: this can potentially use SIMD optimizations with vector libraries. + // We handle both the 1 -> N and N -> N case here. + const float* source = sourceBus.channel(0)->data(); + for (unsigned channelIndex = 0; channelIndex < numberOfChannels(); ++channelIndex) { + if (sourceBus.numberOfChannels() == numberOfChannels()) + source = sourceBus.channel(channelIndex)->data(); + float* destination = channel(channelIndex)->data(); + for (unsigned i = 0; i < numberOfGainValues; ++i) + destination[i] = source[i] * gainValues[i]; + } +} + void AudioBus::copyWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain) { processWithGainFrom(sourceBus, lastMixGain, targetGain, false); diff --git a/Source/WebCore/platform/audio/AudioBus.h b/Source/WebCore/platform/audio/AudioBus.h index 1943c0d164a4..a87f55d3132e 100644 --- a/Source/WebCore/platform/audio/AudioBus.h +++ b/Source/WebCore/platform/audio/AudioBus.h @@ -124,6 +124,9 @@ public: void copyWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain); void sumWithGainFrom(const AudioBus &sourceBus, double* lastMixGain, double targetGain); + // Copies the sourceBus by scaling with sample-accurate gain values. + void copyWithSampleAccurateGainValuesFrom(const AudioBus &sourceBus, float* gainValues, unsigned numberOfGainValues); + // Returns maximum absolute value across all channels (useful for normalization). float maxAbsValue() const; diff --git a/Source/WebCore/webaudio/AudioBufferSourceNode.cpp b/Source/WebCore/webaudio/AudioBufferSourceNode.cpp index fd1bda7a13cc..2fab888e3a96 100644 --- a/Source/WebCore/webaudio/AudioBufferSourceNode.cpp +++ b/Source/WebCore/webaudio/AudioBufferSourceNode.cpp @@ -66,6 +66,9 @@ AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* context, double sampl m_gain = AudioGain::create("gain", 1.0, 0.0, 1.0); m_playbackRate = AudioParam::create("playbackRate", 1.0, 0.0, AudioResampler::MaxRate); + + m_gain->setContext(context); + m_playbackRate->setContext(context); // 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))); diff --git a/Source/WebCore/webaudio/AudioGainNode.cpp b/Source/WebCore/webaudio/AudioGainNode.cpp index 5b9af07ee405..d5f130181b8c 100644 --- a/Source/WebCore/webaudio/AudioGainNode.cpp +++ b/Source/WebCore/webaudio/AudioGainNode.cpp @@ -37,8 +37,10 @@ namespace WebCore { AudioGainNode::AudioGainNode(AudioContext* context, double sampleRate) : AudioNode(context, sampleRate) , m_lastGain(1.0) + , m_sampleAccurateGainValues(AudioNode::ProcessingSizeInFrames) // FIXME: can probably share temp buffer in context { m_gain = AudioGain::create("gain", 1.0, 0.0, 1.0); + m_gain->setContext(context); addInput(adoptPtr(new AudioNodeInput(this))); addOutput(adoptPtr(new AudioNodeOutput(this, 1))); @@ -48,9 +50,9 @@ AudioGainNode::AudioGainNode(AudioContext* context, double sampleRate) initialize(); } -void AudioGainNode::process(size_t /*framesToProcess*/) +void AudioGainNode::process(size_t framesToProcess) { - // FIXME: there is a nice optimization to avoid processing here, and let the gain change + // FIXME: for some cases 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: @@ -64,8 +66,18 @@ void AudioGainNode::process(size_t /*framesToProcess*/) else { AudioBus* inputBus = input(0)->bus(); - // Apply the gain with de-zippering into the output bus. - outputBus->copyWithGainFrom(*inputBus, &m_lastGain, gain()->value()); + if (gain()->hasTimelineValues()) { + // Apply sample-accurate gain scaling for precise envelopes, grain windows, etc. + ASSERT(framesToProcess <= m_sampleAccurateGainValues.size()); + if (framesToProcess <= m_sampleAccurateGainValues.size()) { + float* gainValues = m_sampleAccurateGainValues.data(); + gain()->calculateSampleAccurateValues(gainValues, framesToProcess); + outputBus->copyWithSampleAccurateGainValuesFrom(*inputBus, gainValues, framesToProcess); + } + } else { + // Apply the gain with de-zippering into the output bus. + outputBus->copyWithGainFrom(*inputBus, &m_lastGain, gain()->value()); + } } m_processLock.unlock(); diff --git a/Source/WebCore/webaudio/AudioGainNode.h b/Source/WebCore/webaudio/AudioGainNode.h index 3710472f359c..a0d3c2b208aa 100644 --- a/Source/WebCore/webaudio/AudioGainNode.h +++ b/Source/WebCore/webaudio/AudioGainNode.h @@ -60,6 +60,8 @@ private: double m_lastGain; // for de-zippering RefPtr m_gain; + AudioFloatArray m_sampleAccurateGainValues; + // 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; diff --git a/Source/WebCore/webaudio/HighPass2FilterNode.cpp b/Source/WebCore/webaudio/HighPass2FilterNode.cpp index ca33784d6248..12d58a8edf80 100644 --- a/Source/WebCore/webaudio/HighPass2FilterNode.cpp +++ b/Source/WebCore/webaudio/HighPass2FilterNode.cpp @@ -34,6 +34,9 @@ HighPass2FilterNode::HighPass2FilterNode(AudioContext* context, double sampleRat : AudioBasicProcessorNode(context, sampleRate) { m_processor = adoptPtr(new BiquadProcessor(BiquadProcessor::HighPass2, sampleRate, 1, false)); + biquadProcessor()->parameter1()->setContext(context); + biquadProcessor()->parameter2()->setContext(context); + biquadProcessor()->parameter3()->setContext(context); setType(NodeTypeHighPass2Filter); } diff --git a/Source/WebCore/webaudio/LowPass2FilterNode.cpp b/Source/WebCore/webaudio/LowPass2FilterNode.cpp index 691f4ed73ff2..8e627634daff 100644 --- a/Source/WebCore/webaudio/LowPass2FilterNode.cpp +++ b/Source/WebCore/webaudio/LowPass2FilterNode.cpp @@ -34,6 +34,9 @@ LowPass2FilterNode::LowPass2FilterNode(AudioContext* context, double sampleRate) : AudioBasicProcessorNode(context, sampleRate) { m_processor = adoptPtr(new BiquadProcessor(BiquadProcessor::LowPass2, sampleRate, 1, false)); + biquadProcessor()->parameter1()->setContext(context); + biquadProcessor()->parameter2()->setContext(context); + biquadProcessor()->parameter3()->setContext(context); setType(NodeTypeLowPass2Filter); } -- 2.36.0