Diff
Modified: trunk/Source/WebCore/ChangeLog (108270 => 108271)
--- trunk/Source/WebCore/ChangeLog 2012-02-21 00:25:47 UTC (rev 108270)
+++ trunk/Source/WebCore/ChangeLog 2012-02-21 00:57:20 UTC (rev 108271)
@@ -1,3 +1,30 @@
+2012-02-20 Yuta Kitamura <[email protected]>
+
+ Unreviewed, rolling out r108263.
+ http://trac.webkit.org/changeset/108263
+ https://bugs.webkit.org/show_bug.cgi?id=77856
+
+ Broke Chromium Windows build.
+
+ * platform/audio/DynamicsCompressor.cpp:
+ (WebCore::DynamicsCompressor::DynamicsCompressor):
+ (WebCore::DynamicsCompressor::setEmphasisStageParameters):
+ (WebCore::DynamicsCompressor::process):
+ (WebCore::DynamicsCompressor::reset):
+ * platform/audio/DynamicsCompressor.h:
+ (WebCore::DynamicsCompressor::isStereo):
+ (DynamicsCompressor):
+ * platform/audio/DynamicsCompressorKernel.cpp:
+ (WebCore::DynamicsCompressorKernel::DynamicsCompressorKernel):
+ (WebCore::DynamicsCompressorKernel::setPreDelayTime):
+ (WebCore::DynamicsCompressorKernel::process):
+ (WebCore::DynamicsCompressorKernel::reset):
+ * platform/audio/DynamicsCompressorKernel.h:
+ (DynamicsCompressorKernel):
+ * webaudio/DynamicsCompressorNode.cpp:
+ (WebCore::DynamicsCompressorNode::DynamicsCompressorNode):
+ (WebCore::DynamicsCompressorNode::initialize):
+
2012-02-20 Raymond Liu <[email protected]>
Have the DynamicsCompressorNode support multi-channel data
Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressor.cpp (108270 => 108271)
--- trunk/Source/WebCore/platform/audio/DynamicsCompressor.cpp 2012-02-21 00:25:47 UTC (rev 108270)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressor.cpp 2012-02-21 00:57:20 UTC (rev 108271)
@@ -40,20 +40,16 @@
using namespace AudioUtilities;
-DynamicsCompressor::DynamicsCompressor(float sampleRate, unsigned numberOfChannels)
- : m_numberOfChannels(numberOfChannels)
- , m_compressor(sampleRate, numberOfChannels)
+DynamicsCompressor::DynamicsCompressor(bool isStereo, float sampleRate)
+ : m_isStereo(isStereo)
+ , m_sampleRate(sampleRate)
+ , m_compressor(sampleRate)
{
// Uninitialized state - for parameter recalculation.
m_lastFilterStageRatio = -1;
m_lastAnchor = -1;
m_lastFilterStageGain = -1;
- for (unsigned i = 0; i < numberOfChannels; ++i) {
- m_preFilterPacks.append(adoptPtr(new ZeroPoleFilterPack4()));
- m_postFilterPacks.append(adoptPtr(new ZeroPoleFilterPack4()));
- }
-
initializeParameters();
}
@@ -97,20 +93,18 @@
float r1 = expf(-f1 * piFloat);
float r2 = expf(-f2 * piFloat);
- ASSERT(m_numberOfChannels == m_preFilterPacks.size());
+ // Set pre-filter zero and pole to create an emphasis filter.
+ m_preFilter[stageIndex].setZero(r1);
+ m_preFilter[stageIndex].setPole(r2);
+ m_preFilterR[stageIndex].setZero(r1);
+ m_preFilterR[stageIndex].setPole(r2);
- for (unsigned i = 0; i < m_numberOfChannels; ++i) {
- // Set pre-filter zero and pole to create an emphasis filter.
- ZeroPole& preFilter = m_preFilterPacks[i]->filters[stageIndex];
- preFilter.setZero(r1);
- preFilter.setPole(r2);
-
- // Set post-filter with zero and pole reversed to create the de-emphasis filter.
- // If there were no compressor kernel in between, they would cancel each other out (allpass filter).
- ZeroPole& postFilter = m_postFilterPacks[i]->filters[stageIndex];
- postFilter.setZero(r2);
- postFilter.setPole(r1);
- }
+ // Set post-filter with zero and pole reversed to create the de-emphasis filter.
+ // If there were no compressor kernel in between, they would cancel each other out (allpass filter).
+ m_postFilter[stageIndex].setZero(r2);
+ m_postFilter[stageIndex].setPole(r1);
+ m_postFilterR[stageIndex].setZero(r2);
+ m_postFilterR[stageIndex].setPole(r1);
}
void DynamicsCompressor::setEmphasisParameters(float gain, float anchorFreq, float filterStageRatio)
@@ -123,44 +117,19 @@
void DynamicsCompressor::process(const AudioBus* sourceBus, AudioBus* destinationBus, unsigned framesToProcess)
{
- // Though numberOfChannels is retrived from destinationBus, we still name it numberOfChannels instead of numberOfDestinationChannels.
- // It's because we internally match sourceChannels's size to destinationBus by channel up/down mix. Thus we need numberOfChannels
- // to do the loop work for both sourceChannels and destinationChannels.
+ const float* sourceL = sourceBus->channel(0)->data();
+ const float* sourceR;
- unsigned numberOfChannels = destinationBus->numberOfChannels();
- unsigned numberOfSourceChannels = sourceBus->numberOfChannels();
+ if (sourceBus->numberOfChannels() > 1)
+ sourceR = sourceBus->channel(1)->data();
+ else
+ sourceR = sourceL;
- ASSERT(numberOfSourceChannels);
+ ASSERT(destinationBus->numberOfChannels() == 2);
- if (!numberOfSourceChannels) {
- destinationBus->zero();
- return;
- }
+ float* destinationL = destinationBus->channel(0)->mutableData();
+ float* destinationR = destinationBus->channel(1)->mutableData();
- const float* sourceChannels[numberOfChannels];
- float* destinationChannels[numberOfChannels];
-
- switch (numberOfChannels) {
- case 2: // stereo
- sourceChannels[0] = sourceBus->channel(0)->data();
-
- if (numberOfSourceChannels > 1)
- sourceChannels[1] = sourceBus->channel(1)->data();
- else
- // Simply duplicate mono channel input data to right channel for stereo processing.
- sourceChannels[1] = sourceChannels[0];
-
- break;
- default:
- // FIXME : support other number of channels.
- ASSERT_NOT_REACHED();
- destinationBus->zero();
- return;
- }
-
- for (unsigned i = 0; i < numberOfChannels; ++i)
- destinationChannels[i] = destinationBus->channel(i)->mutableData();
-
float filterStageGain = parameterValue(ParamFilterStageGain);
float filterStageRatio = parameterValue(ParamFilterStageRatio);
float anchor = parameterValue(ParamFilterAnchor);
@@ -175,15 +144,16 @@
// Apply pre-emphasis filter.
// Note that the final three stages are computed in-place in the destination buffer.
- for (unsigned i = 0; i < numberOfChannels; ++i) {
- const float* sourceData = sourceChannels[i];
- float* destinationData = destinationChannels[i];
- ZeroPole* preFilters = m_preFilterPacks[i]->filters;
+ m_preFilter[0].process(sourceL, destinationL, framesToProcess);
+ m_preFilter[1].process(destinationL, destinationL, framesToProcess);
+ m_preFilter[2].process(destinationL, destinationL, framesToProcess);
+ m_preFilter[3].process(destinationL, destinationL, framesToProcess);
- preFilters[0].process(sourceData, destinationData, framesToProcess);
- preFilters[1].process(destinationData, destinationData, framesToProcess);
- preFilters[2].process(destinationData, destinationData, framesToProcess);
- preFilters[3].process(destinationData, destinationData, framesToProcess);
+ if (isStereo()) {
+ m_preFilterR[0].process(sourceR, destinationR, framesToProcess);
+ m_preFilterR[1].process(destinationR, destinationR, framesToProcess);
+ m_preFilterR[2].process(destinationR, destinationR, framesToProcess);
+ m_preFilterR[3].process(destinationR, destinationR, framesToProcess);
}
float dbThreshold = parameterValue(ParamThreshold);
@@ -207,9 +177,10 @@
// Apply compression to the pre-filtered signal.
// The processing is performed in place.
- m_compressor.process(destinationChannels,
- destinationChannels,
- numberOfChannels,
+ m_compressor.process(destinationL,
+ destinationL,
+ destinationR,
+ destinationR,
framesToProcess,
dbThreshold,
@@ -227,14 +198,16 @@
);
// Apply de-emphasis filter.
- for (unsigned i = 0; i < numberOfChannels; ++i) {
- float* destinationData = destinationChannels[i];
- ZeroPole* postFilters = m_postFilterPacks[i]->filters;
+ m_postFilter[0].process(destinationL, destinationL, framesToProcess);
+ m_postFilter[1].process(destinationL, destinationL, framesToProcess);
+ m_postFilter[2].process(destinationL, destinationL, framesToProcess);
+ m_postFilter[3].process(destinationL, destinationL, framesToProcess);
- postFilters[0].process(destinationData, destinationData, framesToProcess);
- postFilters[1].process(destinationData, destinationData, framesToProcess);
- postFilters[2].process(destinationData, destinationData, framesToProcess);
- postFilters[3].process(destinationData, destinationData, framesToProcess);
+ if (isStereo()) {
+ m_postFilterR[0].process(destinationR, destinationR, framesToProcess);
+ m_postFilterR[1].process(destinationR, destinationR, framesToProcess);
+ m_postFilterR[2].process(destinationR, destinationR, framesToProcess);
+ m_postFilterR[3].process(destinationR, destinationR, framesToProcess);
}
}
@@ -244,32 +217,16 @@
m_lastAnchor = -1;
m_lastFilterStageGain = -1;
- for (unsigned channel = 0; channel < m_numberOfChannels; ++channel) {
- for (unsigned stageIndex = 0; stageIndex < 4; ++stageIndex) {
- m_preFilterPacks[channel]->filters[stageIndex].reset();
- m_postFilterPacks[channel]->filters[stageIndex].reset();
- }
+ for (unsigned i = 0; i < 4; ++i) {
+ m_preFilter[i].reset();
+ m_preFilterR[i].reset();
+ m_postFilter[i].reset();
+ m_postFilterR[i].reset();
}
m_compressor.reset();
}
-void DynamicsCompressor::setNumberOfChannels(unsigned numberOfChannels)
-{
- if (m_preFilterPacks.size() == numberOfChannels)
- return;
-
- m_preFilterPacks.clear();
- m_postFilterPacks.clear();
- for (unsigned i = 0; i < numberOfChannels; ++i) {
- m_preFilterPacks.append(adoptPtr(new ZeroPoleFilterPack4()));
- m_postFilterPacks.append(adoptPtr(new ZeroPoleFilterPack4()));
- }
-
- m_compressor.setNumberOfChannels(numberOfChannels);
- m_numberOfChannels = numberOfChannels;
-}
-
} // namespace WebCore
#endif // ENABLE(WEB_AUDIO)
Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressor.h (108270 => 108271)
--- trunk/Source/WebCore/platform/audio/DynamicsCompressor.h 2012-02-21 00:25:47 UTC (rev 108270)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressor.h 2012-02-21 00:57:20 UTC (rev 108271)
@@ -62,26 +62,25 @@
ParamLast
};
- DynamicsCompressor(float sampleRate, unsigned numberOfChannels);
+ DynamicsCompressor(bool isStereo, float sampleRate);
void process(const AudioBus* sourceBus, AudioBus* destinationBus, unsigned framesToProcess);
void reset();
- void setNumberOfChannels(unsigned);
float parameterValue(unsigned parameterID);
+ bool isStereo() const { return m_isStereo; }
float sampleRate() const { return m_sampleRate; }
float nyquist() const { return m_sampleRate / 2; }
protected:
- unsigned m_numberOfChannels;
-
// m_parameters holds the tweakable compressor parameters.
// FIXME: expose some of the most important ones (such as threshold, attack, release)
// as DynamicsCompressorNode attributes.
float m_parameters[ParamLast];
void initializeParameters();
+ bool m_isStereo;
float m_sampleRate;
// Emphasis filter controls.
@@ -89,14 +88,12 @@
float m_lastAnchor;
float m_lastFilterStageGain;
- typedef struct {
- ZeroPole filters[4];
- } ZeroPoleFilterPack4;
+ // Emphasis filters.
+ ZeroPole m_preFilter[4];
+ ZeroPole m_preFilterR[4];
+ ZeroPole m_postFilter[4];
+ ZeroPole m_postFilterR[4];
- // Per-channel emphasis filters.
- Vector<OwnPtr<ZeroPoleFilterPack4> > m_preFilterPacks;
- Vector<OwnPtr<ZeroPoleFilterPack4> > m_postFilterPacks;
-
void setEmphasisStageParameters(unsigned stageIndex, float gain, float normalizedFrequency /* 0 -> 1 */);
void setEmphasisParameters(float gain, float anchorFreq, float filterStageRatio);
Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.cpp (108270 => 108271)
--- trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.cpp 2012-02-21 00:25:47 UTC (rev 108270)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.cpp 2012-02-21 00:57:20 UTC (rev 108271)
@@ -52,30 +52,20 @@
return 1 - exp(-k * x);
}
-DynamicsCompressorKernel::DynamicsCompressorKernel(float sampleRate, unsigned numberOfChannels)
+DynamicsCompressorKernel::DynamicsCompressorKernel(float sampleRate)
: m_sampleRate(sampleRate)
, m_lastPreDelayFrames(DefaultPreDelayFrames)
+ , m_preDelayBufferL(MaxPreDelayFrames)
+ , m_preDelayBufferR(MaxPreDelayFrames)
, m_preDelayReadIndex(0)
, m_preDelayWriteIndex(DefaultPreDelayFrames)
{
- setNumberOfChannels(numberOfChannels);
-
// Initializes most member variables
reset();
m_meteringReleaseK = discreteTimeConstantForSampleRate(meteringReleaseTimeConstant, sampleRate);
}
-void DynamicsCompressorKernel::setNumberOfChannels(unsigned numberOfChannels)
-{
- if (m_preDelayBuffers.size() == numberOfChannels)
- return;
-
- m_preDelayBuffers.clear();
- for (unsigned i = 0; i < numberOfChannels; ++i)
- m_preDelayBuffers.append(adoptPtr(new AudioFloatArray(MaxPreDelayFrames)));
-}
-
void DynamicsCompressorKernel::setPreDelayTime(float preDelayTime)
{
// Re-configure look-ahead section pre-delay if delay time has changed.
@@ -85,17 +75,17 @@
if (m_lastPreDelayFrames != preDelayFrames) {
m_lastPreDelayFrames = preDelayFrames;
- for (unsigned i = 0; i < m_preDelayBuffers.size(); ++i)
- m_preDelayBuffers[i]->zero();
-
+ m_preDelayBufferL.zero();
+ m_preDelayBufferR.zero();
m_preDelayReadIndex = 0;
m_preDelayWriteIndex = preDelayFrames;
}
}
-void DynamicsCompressorKernel::process(float* sourceChannels[],
- float* destinationChannels[],
- unsigned numberOfChannels,
+void DynamicsCompressorKernel::process(const float* sourceL,
+ float* destinationL,
+ const float* sourceR, /* stereo-linked */
+ float* destinationR,
unsigned framesToProcess,
float dbThreshold,
@@ -112,8 +102,7 @@
float releaseZone4
)
{
- ASSERT(m_preDelayBuffers.size() == numberOfChannels);
-
+ bool isStereo = destinationR;
float sampleRate = this->sampleRate();
float dryMix = 1 - effectBlend;
@@ -175,7 +164,6 @@
const int nDivisions = framesToProcess / nDivisionFrames;
- unsigned frameIndex = 0;
for (int i = 0; i < nDivisions; ++i) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Calculate desired gain
@@ -259,6 +247,8 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
+ float* delayBufferL = m_preDelayBufferL.data();
+ float* delayBufferR = m_preDelayBufferR.data();
int preDelayReadIndex = m_preDelayReadIndex;
int preDelayWriteIndex = m_preDelayWriteIndex;
float detectorAverage = m_detectorAverage;
@@ -266,19 +256,32 @@
int loopFrames = nDivisionFrames;
while (loopFrames--) {
- float compressorInput = 0;
+ float compressorInput;
+ float inputL;
+ float inputR = 0;
// Predelay signal, computing compression amount from un-delayed version.
- for (unsigned i = 0; i < numberOfChannels; ++i) {
- float* delayBuffer = m_preDelayBuffers[i]->data();
- float undelayedSource = sourceChannels[i][frameIndex];
- delayBuffer[preDelayWriteIndex] = undelayedSource;
+ if (isStereo) {
+ float undelayedL = *sourceL++;
+ float undelayedR = *sourceR++;
- float absUndelayedSource = undelayedSource > 0 ? undelayedSource : -undelayedSource;
- if (compressorInput < absUndelayedSource)
- compressorInput = absUndelayedSource;
+ compressorInput = 0.5f * (undelayedL + undelayedR);
+
+ inputL = delayBufferL[preDelayReadIndex];
+ inputR = delayBufferR[preDelayReadIndex];
+
+ delayBufferL[preDelayWriteIndex] = undelayedL;
+ delayBufferR[preDelayWriteIndex] = undelayedR;
+ } else {
+ compressorInput = *sourceL++;
+
+ inputL = delayBufferL[preDelayReadIndex];
+ delayBufferL[preDelayWriteIndex] = compressorInput;
}
+ preDelayReadIndex = (preDelayReadIndex + 1) & MaxPreDelayFramesMask;
+ preDelayWriteIndex = (preDelayWriteIndex + 1) & MaxPreDelayFramesMask;
+
// Calculate shaped power on undelayed input.
float scaledInput = compressorInput;
@@ -334,14 +337,17 @@
m_meteringGain += (dbRealGain - m_meteringGain) * m_meteringReleaseK;
// Apply final gain.
- for (unsigned i = 0; i < numberOfChannels; ++i) {
- float* delayBuffer = m_preDelayBuffers[i]->data();
- destinationChannels[i][frameIndex] = delayBuffer[preDelayReadIndex] * totalGain;
- }
+ if (isStereo) {
+ float outputL = inputL;
+ float outputR = inputR;
- frameIndex++;
- preDelayReadIndex = (preDelayReadIndex + 1) & MaxPreDelayFramesMask;
- preDelayWriteIndex = (preDelayWriteIndex + 1) & MaxPreDelayFramesMask;
+ outputL *= totalGain;
+ outputR *= totalGain;
+
+ *destinationL++ = outputL;
+ *destinationR++ = outputR;
+ } else
+ *destinationL++ = inputL * totalGain;
}
// Locals back to member variables.
@@ -360,9 +366,8 @@
m_meteringGain = 1;
// Predelay section.
- for (unsigned i = 0; i < m_preDelayBuffers.size(); ++i)
- m_preDelayBuffers[i]->zero();
-
+ m_preDelayBufferL.zero();
+ m_preDelayBufferR.zero();
m_preDelayReadIndex = 0;
m_preDelayWriteIndex = DefaultPreDelayFrames;
Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.h (108270 => 108271)
--- trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.h 2012-02-21 00:25:47 UTC (rev 108270)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.h 2012-02-21 00:57:20 UTC (rev 108271)
@@ -31,21 +31,17 @@
#include "AudioArray.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
-
namespace WebCore {
class DynamicsCompressorKernel {
public:
- DynamicsCompressorKernel(float sampleRate, unsigned numberOfChannels);
+ DynamicsCompressorKernel(float sampleRate);
- void setNumberOfChannels(unsigned);
-
// Performs stereo-linked compression.
- void process(float* sourceChannels[],
- float* destinationChannels[],
- unsigned numberOfChannels,
+ void process(const float *sourceL,
+ float *destinationL,
+ const float *sourceR,
+ float *destinationR,
unsigned framesToProcess,
float dbThreshold,
@@ -70,7 +66,7 @@
protected:
float m_sampleRate;
-
+
float m_detectorAverage;
float m_compressorGain;
@@ -85,7 +81,8 @@
unsigned m_lastPreDelayFrames;
void setPreDelayTime(float);
- Vector<OwnPtr<AudioFloatArray> > m_preDelayBuffers;
+ AudioFloatArray m_preDelayBufferL;
+ AudioFloatArray m_preDelayBufferR;
int m_preDelayReadIndex;
int m_preDelayWriteIndex;
Modified: trunk/Source/WebCore/webaudio/DynamicsCompressorNode.cpp (108270 => 108271)
--- trunk/Source/WebCore/webaudio/DynamicsCompressorNode.cpp 2012-02-21 00:25:47 UTC (rev 108270)
+++ trunk/Source/WebCore/webaudio/DynamicsCompressorNode.cpp 2012-02-21 00:57:20 UTC (rev 108271)
@@ -33,16 +33,13 @@
#include "AudioNodeOutput.h"
#include "DynamicsCompressor.h"
-// Set output to stereo by default.
-static const unsigned defaultNumberOfOutputChannels = 2;
-
namespace WebCore {
DynamicsCompressorNode::DynamicsCompressorNode(AudioContext* context, float sampleRate)
: AudioNode(context, sampleRate)
{
addInput(adoptPtr(new AudioNodeInput(this)));
- addOutput(adoptPtr(new AudioNodeOutput(this, defaultNumberOfOutputChannels)));
+ addOutput(adoptPtr(new AudioNodeOutput(this, 2)));
setNodeType(NodeTypeDynamicsCompressor);
@@ -73,7 +70,7 @@
return;
AudioNode::initialize();
- m_dynamicsCompressor = adoptPtr(new DynamicsCompressor(sampleRate(), defaultNumberOfOutputChannels));
+ m_dynamicsCompressor = adoptPtr(new DynamicsCompressor(true, sampleRate()));
}
void DynamicsCompressorNode::uninitialize()