Title: [109023] trunk
Revision
109023
Author
crog...@google.com
Date
2012-02-27 14:15:11 -0800 (Mon, 27 Feb 2012)

Log Message

Implement static compression curve parameters for DynamicsCompressorNode
https://bugs.webkit.org/show_bug.cgi?id=78937

Reviewed by Kenneth Russell.

Source/WebCore:

Test: webaudio/dynamicscompressor-basic.html

* platform/audio/DynamicsCompressor.cpp:
(WebCore::DynamicsCompressor::setParameterValue):
(WebCore):
(WebCore::DynamicsCompressor::initializeParameters):
(WebCore::DynamicsCompressor::process):
* platform/audio/DynamicsCompressor.h:
* platform/audio/DynamicsCompressorKernel.cpp:
(WebCore):
(WebCore::DynamicsCompressorKernel::DynamicsCompressorKernel):
(WebCore::DynamicsCompressorKernel::setPreDelayTime):
(WebCore::DynamicsCompressorKernel::kneeCurve):
(WebCore::DynamicsCompressorKernel::saturate):
(WebCore::DynamicsCompressorKernel::slopeAt):
(WebCore::DynamicsCompressorKernel::kAtSlope):
(WebCore::DynamicsCompressorKernel::updateStaticCurveParameters):
(WebCore::DynamicsCompressorKernel::process):
* platform/audio/DynamicsCompressorKernel.h:
(DynamicsCompressorKernel):
(WebCore::DynamicsCompressorKernel::meteringGain):
* webaudio/DynamicsCompressorNode.cpp:
(WebCore::DynamicsCompressorNode::DynamicsCompressorNode):
(WebCore::DynamicsCompressorNode::process):
* webaudio/DynamicsCompressorNode.h:
(WebCore):
(WebCore::DynamicsCompressorNode::create):
(DynamicsCompressorNode):
(WebCore::DynamicsCompressorNode::threshold):
(WebCore::DynamicsCompressorNode::knee):
(WebCore::DynamicsCompressorNode::ratio):
(WebCore::DynamicsCompressorNode::reduction):
* webaudio/DynamicsCompressorNode.idl:

LayoutTests:

* webaudio/dynamicscompressor-basic-expected.txt: Added.
* webaudio/dynamicscompressor-basic.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (109022 => 109023)


--- trunk/LayoutTests/ChangeLog	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/LayoutTests/ChangeLog	2012-02-27 22:15:11 UTC (rev 109023)
@@ -1,3 +1,13 @@
+2012-02-27  Chris Rogers  <crog...@google.com>
+
+        Implement static compression curve parameters for DynamicsCompressorNode
+        https://bugs.webkit.org/show_bug.cgi?id=78937
+
+        Reviewed by Kenneth Russell.
+
+        * webaudio/dynamicscompressor-basic-expected.txt: Added.
+        * webaudio/dynamicscompressor-basic.html: Added.
+
 2012-02-27  Oliver Hunt  <oli...@apple.com>
 
         REGRESSION (r108112): AWS Management Console at amazon.com fails to initialize

Added: trunk/LayoutTests/webaudio/dynamicscompressor-basic-expected.txt (0 => 109023)


--- trunk/LayoutTests/webaudio/dynamicscompressor-basic-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/webaudio/dynamicscompressor-basic-expected.txt	2012-02-27 22:15:11 UTC (rev 109023)
@@ -0,0 +1,11 @@
+Basic tests for DynamicsCompressorNode API.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS threshold attribute has correct default value.
+PASS knee attribute has correct default value.
+PASS ratio attribute has correct default value.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/webaudio/dynamicscompressor-basic.html (0 => 109023)


--- trunk/LayoutTests/webaudio/dynamicscompressor-basic.html	                        (rev 0)
+++ trunk/LayoutTests/webaudio/dynamicscompressor-basic.html	2012-02-27 22:15:11 UTC (rev 109023)
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+<script src=""
+<script type="text/_javascript_" src=""
+</head>
+
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Basic tests for DynamicsCompressorNode API.");
+
+var context;
+var compressor;
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    
+    window.jsTestIsAsync = true;
+
+    context = new webkitAudioContext();
+    compressor = context.createDynamicsCompressor();
+
+    try {
+        if (compressor.threshold.value == -24)
+            testPassed("threshold attribute has correct default value.");
+        else
+            testFailed("threshold attribute has incorrect default value.");
+
+        if (compressor.knee.value == 30)
+            testPassed("knee attribute has correct default value.");
+        else
+            testFailed("knee attribute has incorrect default value.");
+        
+        if (compressor.ratio.value == 12)
+            testPassed("ratio attribute has correct default value.");
+        else
+            testFailed("ratio attribute has incorrect default value.");
+        
+    } catch(e) {
+        testFailed("Exception thrown when accessing DynamicsCompressorNode attributes.");
+    }
+
+    finishJSTest();
+}
+
+runTest();
+
+</script>
+
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (109022 => 109023)


--- trunk/Source/WebCore/ChangeLog	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/ChangeLog	2012-02-27 22:15:11 UTC (rev 109023)
@@ -1,3 +1,44 @@
+2012-02-27  Chris Rogers  <crog...@google.com>
+
+        Implement static compression curve parameters for DynamicsCompressorNode
+        https://bugs.webkit.org/show_bug.cgi?id=78937
+
+        Reviewed by Kenneth Russell.
+
+        Test: webaudio/dynamicscompressor-basic.html
+
+        * platform/audio/DynamicsCompressor.cpp:
+        (WebCore::DynamicsCompressor::setParameterValue):
+        (WebCore):
+        (WebCore::DynamicsCompressor::initializeParameters):
+        (WebCore::DynamicsCompressor::process):
+        * platform/audio/DynamicsCompressor.h:
+        * platform/audio/DynamicsCompressorKernel.cpp:
+        (WebCore):
+        (WebCore::DynamicsCompressorKernel::DynamicsCompressorKernel):
+        (WebCore::DynamicsCompressorKernel::setPreDelayTime):
+        (WebCore::DynamicsCompressorKernel::kneeCurve):
+        (WebCore::DynamicsCompressorKernel::saturate):
+        (WebCore::DynamicsCompressorKernel::slopeAt):
+        (WebCore::DynamicsCompressorKernel::kAtSlope):
+        (WebCore::DynamicsCompressorKernel::updateStaticCurveParameters):
+        (WebCore::DynamicsCompressorKernel::process):
+        * platform/audio/DynamicsCompressorKernel.h:
+        (DynamicsCompressorKernel):
+        (WebCore::DynamicsCompressorKernel::meteringGain):
+        * webaudio/DynamicsCompressorNode.cpp:
+        (WebCore::DynamicsCompressorNode::DynamicsCompressorNode):
+        (WebCore::DynamicsCompressorNode::process):
+        * webaudio/DynamicsCompressorNode.h:
+        (WebCore):
+        (WebCore::DynamicsCompressorNode::create):
+        (DynamicsCompressorNode):
+        (WebCore::DynamicsCompressorNode::threshold):
+        (WebCore::DynamicsCompressorNode::knee):
+        (WebCore::DynamicsCompressorNode::ratio):
+        (WebCore::DynamicsCompressorNode::reduction):
+        * webaudio/DynamicsCompressorNode.idl:
+
 2012-02-27  Enrica Casucci  <enr...@apple.com>
 
         WebKit2: implement platform strategy to access Pasteboard in the UI process.

Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressor.cpp (109022 => 109023)


--- trunk/Source/WebCore/platform/audio/DynamicsCompressor.cpp	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressor.cpp	2012-02-27 22:15:11 UTC (rev 109023)
@@ -53,12 +53,20 @@
     initializeParameters();
 }
 
+void DynamicsCompressor::setParameterValue(unsigned parameterID, float value)
+{
+    ASSERT(parameterID < ParamLast);
+    if (parameterID < ParamLast)
+        m_parameters[parameterID] = value;
+}
+
 void DynamicsCompressor::initializeParameters()
 {
     // Initializes compressor to default values.
     
     m_parameters[ParamThreshold] = -24; // dB
-    m_parameters[ParamHeadroom] = 21; // dB
+    m_parameters[ParamKnee] = 30; // dB
+    m_parameters[ParamRatio] = 12; // unit-less
     m_parameters[ParamAttack] = 0.003f; // seconds
     m_parameters[ParamRelease] = 0.250f; // seconds
     m_parameters[ParamPreDelay] = 0.006f; // seconds
@@ -74,6 +82,7 @@
     m_parameters[ParamFilterAnchor] = 15000 / nyquist();
     
     m_parameters[ParamPostGain] = 0; // dB
+    m_parameters[ParamReduction] = 0; // dB
 
     // Linear crossfade (0 -> 1).
     m_parameters[ParamEffectBlend] = 1;
@@ -180,7 +189,8 @@
     }
 
     float dbThreshold = parameterValue(ParamThreshold);
-    float dbHeadroom = parameterValue(ParamHeadroom);
+    float dbKnee = parameterValue(ParamKnee);
+    float ratio = parameterValue(ParamRatio);
     float attackTime = parameterValue(ParamAttack);
     float releaseTime = parameterValue(ParamRelease);
     float preDelayTime = parameterValue(ParamPreDelay);
@@ -206,7 +216,8 @@
                          framesToProcess,
 
                          dbThreshold,
-                         dbHeadroom,
+                         dbKnee,
+                         ratio,
                          attackTime,
                          releaseTime,
                          preDelayTime,
@@ -218,6 +229,9 @@
                          releaseZone3,
                          releaseZone4
                          );
+                         
+    // Update the compression amount.                     
+    setParameterValue(ParamReduction, m_compressor.meteringGain());
 
     // Apply de-emphasis filter.
     for (unsigned i = 0; i < numberOfChannels; ++i) {

Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressor.h (109022 => 109023)


--- trunk/Source/WebCore/platform/audio/DynamicsCompressor.h	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressor.h	2012-02-27 22:15:11 UTC (rev 109023)
@@ -48,7 +48,8 @@
 public:
     enum {
         ParamThreshold,
-        ParamHeadroom,
+        ParamKnee,
+        ParamRatio,
         ParamAttack,
         ParamRelease,
         ParamPreDelay,
@@ -61,6 +62,7 @@
         ParamFilterStageRatio,
         ParamFilterAnchor,
         ParamEffectBlend,
+        ParamReduction,
         ParamLast
     };
 
@@ -70,6 +72,7 @@
     void reset();
     void setNumberOfChannels(unsigned);
 
+    void setParameterValue(unsigned parameterID, float value);
     float parameterValue(unsigned parameterID);
 
     float sampleRate() const { return m_sampleRate; }

Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.cpp (109022 => 109023)


--- trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.cpp	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.cpp	2012-02-27 22:15:11 UTC (rev 109023)
@@ -45,24 +45,29 @@
 
 // Metering hits peaks instantly, but releases this fast (in seconds).
 const float meteringReleaseTimeConstant = 0.325f;
-    
-// Exponential saturation curve.
-static float saturate(float x, float k)
-{
-    return 1 - exp(-k * x);
-}
 
+const float uninitializedValue = -1;
+
 DynamicsCompressorKernel::DynamicsCompressorKernel(float sampleRate, unsigned numberOfChannels)
     : m_sampleRate(sampleRate)
     , m_lastPreDelayFrames(DefaultPreDelayFrames)
     , m_preDelayReadIndex(0)
     , m_preDelayWriteIndex(DefaultPreDelayFrames)
+    , m_ratio(uninitializedValue)
+    , m_slope(uninitializedValue)
+    , m_linearThreshold(uninitializedValue)
+    , m_dbThreshold(uninitializedValue)
+    , m_dbKnee(uninitializedValue)
+    , m_kneeThreshold(uninitializedValue)
+    , m_kneeThresholdDb(uninitializedValue)
+    , m_ykneeThresholdDb(uninitializedValue)
+    , m_K(uninitializedValue)
 {
     setNumberOfChannels(numberOfChannels);
 
     // Initializes most member variables
     reset();
-    
+
     m_meteringReleaseK = discreteTimeConstantForSampleRate(meteringReleaseTimeConstant, sampleRate);
 }
 
@@ -82,7 +87,7 @@
     unsigned preDelayFrames = preDelayTime * sampleRate();
     if (preDelayFrames > MaxPreDelayFrames - 1)
         preDelayFrames = MaxPreDelayFrames - 1;
-        
+
     if (m_lastPreDelayFrames != preDelayFrames) {
         m_lastPreDelayFrames = preDelayFrames;
         for (unsigned i = 0; i < m_preDelayBuffers.size(); ++i)
@@ -93,13 +98,117 @@
     }
 }
 
+// Exponential curve for the knee.
+// It is 1st derivative matched at m_linearThreshold and asymptotically approaches the value m_linearThreshold + 1 / k.
+float DynamicsCompressorKernel::kneeCurve(float x, float k)
+{
+    // Linear up to threshold.
+    if (x < m_linearThreshold)
+        return x;
+
+    return m_linearThreshold + (1 - expf(-k * (x - m_linearThreshold))) / k;
+}
+
+// Full compression curve with constant ratio after knee.
+float DynamicsCompressorKernel::saturate(float x, float k)
+{
+    float y;
+
+    if (x < m_kneeThreshold)
+        y = kneeCurve(x, k);
+    else {
+        // Constant ratio after knee.
+        float xDb = linearToDecibels(x);
+        float yDb = m_ykneeThresholdDb + m_slope * (xDb - m_kneeThresholdDb);
+
+        y = decibelsToLinear(yDb);
+    }
+
+    return y;
+}
+
+// Approximate 1st derivative with input and output expressed in dB.
+// This slope is equal to the inverse of the compression "ratio".
+// In other words, a compression ratio of 20 would be a slope of 1/20.
+float DynamicsCompressorKernel::slopeAt(float x, float k)
+{
+    if (x < m_linearThreshold)
+        return 1;
+
+    float x2 = x * 1.001;
+
+    float xDb = linearToDecibels(x);
+    float x2Db = linearToDecibels(x2);
+
+    float yDb = linearToDecibels(kneeCurve(x, k));
+    float y2Db = linearToDecibels(kneeCurve(x2, k));
+
+    float m = (y2Db - yDb) / (x2Db - xDb);
+
+    return m;
+}
+
+float DynamicsCompressorKernel::kAtSlope(float desiredSlope)
+{
+    float xDb = m_dbThreshold + m_dbKnee;
+    float x = decibelsToLinear(xDb);
+
+    // Approximate k given initial values.
+    float minK = 0.1;
+    float maxK = 10000;
+    float k = 5;
+
+    for (int i = 0; i < 15; ++i) {
+        // A high value for k will more quickly asymptotically approach a slope of 0.
+        float slope = slopeAt(x, k);
+
+        if (slope < desiredSlope) {
+            // k is too high.
+            maxK = k;
+        } else {
+            // k is too low.
+            minK = k;
+        }
+
+        // Re-calculate based on geometric mean.
+        k = sqrtf(minK * maxK);
+    }
+
+    return k;
+}
+
+float DynamicsCompressorKernel::updateStaticCurveParameters(float dbThreshold, float dbKnee, float ratio)
+{
+    if (dbThreshold != m_dbThreshold || dbKnee != m_dbKnee || ratio != m_ratio) {
+        // Threshold and knee.
+        m_dbThreshold = dbThreshold;
+        m_linearThreshold = decibelsToLinear(dbThreshold);
+        m_dbKnee = dbKnee;
+
+        // Compute knee parameters.
+        m_ratio = ratio;
+        m_slope = 1 / m_ratio;
+
+        float k = kAtSlope(1 / m_ratio);
+
+        m_kneeThresholdDb = dbThreshold + dbKnee;
+        m_kneeThreshold = decibelsToLinear(m_kneeThresholdDb);
+
+        m_ykneeThresholdDb = linearToDecibels(kneeCurve(m_kneeThreshold, k));
+
+        m_K = k;
+    }
+    return m_K;
+}
+
 void DynamicsCompressorKernel::process(float* sourceChannels[],
                                        float* destinationChannels[],
                                        unsigned numberOfChannels,
                                        unsigned framesToProcess,
 
                                        float dbThreshold,
-                                       float dbHeadroom,
+                                       float dbKnee,
+                                       float ratio,
                                        float attackTime,
                                        float releaseTime,
                                        float preDelayTime,
@@ -119,17 +228,12 @@
     float dryMix = 1 - effectBlend;
     float wetMix = effectBlend;
 
-    // Threshold and headroom.
-    float linearThreshold = decibelsToLinear(dbThreshold);
-    float linearHeadroom = decibelsToLinear(dbHeadroom);
+    float k = updateStaticCurveParameters(dbThreshold, dbKnee, ratio);
 
     // Makeup gain.
-    float maximum = 1.05f * linearHeadroom * linearThreshold;
-    float kk = (maximum - linearThreshold);
-    float inverseKK = 1 / kk;
+    float fullRangeGain = saturate(1, k);
+    float fullRangeMakeupGain = 1 / fullRangeGain;
 
-    float fullRangeGain = (linearThreshold + kk * saturate(1 - linearThreshold, 1));
-    float fullRangeMakeupGain = 1 / fullRangeGain;
     // Empirical/perceptual tuning.
     fullRangeMakeupGain = powf(fullRangeMakeupGain, 0.6f);
 
@@ -141,7 +245,7 @@
 
     // Release parameters.
     float releaseFrames = sampleRate * releaseTime;
-    
+
     // Detector release time.
     float satReleaseTime = 0.0025f;
     float satReleaseFrames = satReleaseTime * sampleRate;
@@ -170,7 +274,7 @@
     // y calculates adaptive release frames depending on the amount of compression.
 
     setPreDelayTime(preDelayTime);
-    
+
     const int nDivisionFrames = 32;
 
     const int nDivisions = framesToProcess / nDivisionFrames;
@@ -285,9 +389,10 @@
                 float absInput = scaledInput > 0 ? scaledInput : -scaledInput;
 
                 // Put through shaping curve.
-                // This is linear up to the threshold, then exponentially approaches the maximum (headroom amount above threshold).
-                // The transition from the threshold to the exponential portion is smooth (1st derivative matched).
-                float shapedInput = absInput < linearThreshold ? absInput : linearThreshold + kk * saturate(absInput - linearThreshold, inverseKK);
+                // This is linear up to the threshold, then enters a "knee" portion followed by the "ratio" portion.
+                // The transition from the threshold to the knee is smooth (1st derivative matched).
+                // The transition from the knee to the ratio portion is smooth (1st derivative matched).
+                float shapedInput = saturate(absInput, k);
 
                 float attenuation = absInput <= 0.0001f ? 1 : shapedInput / absInput;
 

Modified: trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.h (109022 => 109023)


--- trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.h	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/platform/audio/DynamicsCompressorKernel.h	2012-02-27 22:15:11 UTC (rev 109023)
@@ -49,7 +49,8 @@
                  unsigned framesToProcess,
 
                  float dbThreshold,
-                 float dbHeadroom,
+                 float dbKnee,
+                 float ratio,
                  float attackTime,
                  float releaseTime,
                  float preDelayTime,
@@ -68,6 +69,8 @@
 
     float sampleRate() const { return m_sampleRate; }
 
+    float meteringGain() const { return m_meteringGain; }
+
 protected:
     float m_sampleRate;
 
@@ -90,6 +93,35 @@
     int m_preDelayWriteIndex;
 
     float m_maxAttackCompressionDiffDb;
+
+    // Static compression curve.
+    float kneeCurve(float x, float k);
+    float saturate(float x, float k);
+    float slopeAt(float x, float k);
+    float kAtSlope(float desiredSlope);
+
+    float updateStaticCurveParameters(float dbThreshold, float dbKnee, float ratio);
+
+    // Amount of input change in dB required for 1 dB of output change.
+    // This applies to the portion of the curve above m_kneeThresholdDb (see below).
+    float m_ratio;
+    float m_slope; // Inverse ratio.
+
+    // The input to output change below the threshold is linear 1:1.
+    float m_linearThreshold;
+    float m_dbThreshold;
+
+    // m_dbKnee is the number of dB above the threshold before we enter the "ratio" portion of the curve.
+    // m_kneeThresholdDb = m_dbThreshold + m_dbKnee
+    // The portion between m_dbThreshold and m_kneeThresholdDb is the "soft knee" portion of the curve
+    // which transitions smoothly from the linear portion to the ratio portion.
+    float m_dbKnee;
+    float m_kneeThreshold;
+    float m_kneeThresholdDb;
+    float m_ykneeThresholdDb;
+
+    // Internal parameter for the knee portion of the curve.
+    float m_K;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/webaudio/DynamicsCompressorNode.cpp (109022 => 109023)


--- trunk/Source/WebCore/webaudio/DynamicsCompressorNode.cpp	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/webaudio/DynamicsCompressorNode.cpp	2012-02-27 22:15:11 UTC (rev 109023)
@@ -43,9 +43,19 @@
 {
     addInput(adoptPtr(new AudioNodeInput(this)));
     addOutput(adoptPtr(new AudioNodeOutput(this, defaultNumberOfOutputChannels)));
-    
+
     setNodeType(NodeTypeDynamicsCompressor);
-    
+
+    m_threshold = AudioParam::create("threshold", -24, -100, 0);
+    m_knee = AudioParam::create("knee", 30, 0, 40);
+    m_ratio = AudioParam::create("ratio", 12, 1, 20);
+    m_reduction = AudioParam::create("reduction", 0, -20, 0);
+
+    m_threshold->setContext(context);
+    m_knee->setContext(context);
+    m_ratio->setContext(context);
+    m_reduction->setContext(context);
+
     initialize();
 }
 
@@ -59,7 +69,18 @@
     AudioBus* outputBus = output(0)->bus();
     ASSERT(outputBus);
 
+    float threshold = m_threshold->value();
+    float knee = m_knee->value();
+    float ratio = m_ratio->value();
+
+    m_dynamicsCompressor->setParameterValue(DynamicsCompressor::ParamThreshold, threshold);
+    m_dynamicsCompressor->setParameterValue(DynamicsCompressor::ParamKnee, knee);
+    m_dynamicsCompressor->setParameterValue(DynamicsCompressor::ParamRatio, ratio);
+
     m_dynamicsCompressor->process(input(0)->bus(), outputBus, framesToProcess);
+
+    float reduction = m_dynamicsCompressor->parameterValue(DynamicsCompressor::ParamReduction);
+    m_reduction->setValue(reduction);
 }
 
 void DynamicsCompressorNode::reset()

Modified: trunk/Source/WebCore/webaudio/DynamicsCompressorNode.h (109022 => 109023)


--- trunk/Source/WebCore/webaudio/DynamicsCompressorNode.h	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/webaudio/DynamicsCompressorNode.h	2012-02-27 22:15:11 UTC (rev 109023)
@@ -26,31 +26,44 @@
 #define DynamicsCompressorNode_h
 
 #include "AudioNode.h"
+#include "AudioParam.h"
 #include <wtf/OwnPtr.h>
 
 namespace WebCore {
 
 class DynamicsCompressor;
-    
+
 class DynamicsCompressorNode : public AudioNode {
 public:
     static PassRefPtr<DynamicsCompressorNode> create(AudioContext* context, float sampleRate)
     {
-        return adoptRef(new DynamicsCompressorNode(context, sampleRate));      
+        return adoptRef(new DynamicsCompressorNode(context, sampleRate));
     }
-    
+
     virtual ~DynamicsCompressorNode();
-    
+
     // AudioNode
     virtual void process(size_t framesToProcess);
     virtual void reset();
     virtual void initialize();
     virtual void uninitialize();
 
+    // Static compression curve parameters.
+    AudioParam* threshold() { return m_threshold.get(); }
+    AudioParam* knee() { return m_knee.get(); }
+    AudioParam* ratio() { return m_ratio.get(); }
+
+    // Amount by which the compressor is currently compressing the signal in decibels.
+    AudioParam* reduction() { return m_reduction.get(); }
+
 private:
     DynamicsCompressorNode(AudioContext*, float sampleRate);
 
     OwnPtr<DynamicsCompressor> m_dynamicsCompressor;
+    RefPtr<AudioParam> m_threshold;
+    RefPtr<AudioParam> m_knee;
+    RefPtr<AudioParam> m_ratio;
+    RefPtr<AudioParam> m_reduction;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/webaudio/DynamicsCompressorNode.idl (109022 => 109023)


--- trunk/Source/WebCore/webaudio/DynamicsCompressorNode.idl	2012-02-27 22:03:41 UTC (rev 109022)
+++ trunk/Source/WebCore/webaudio/DynamicsCompressorNode.idl	2012-02-27 22:15:11 UTC (rev 109023)
@@ -27,5 +27,9 @@
         Conditional=WEB_AUDIO,
         JSGenerateToJSObject
     ] DynamicsCompressorNode : AudioNode {
+        readonly attribute AudioParam threshold; // in Decibels
+        readonly attribute AudioParam knee; // in Decibels
+        readonly attribute AudioParam ratio; // unit-less
+        readonly attribute AudioParam reduction; // in Decibels
     };
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to