michael@0: /* michael@0: * Copyright (C) 2011 Google Inc. All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * michael@0: * 1. Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * 2. Redistributions in binary form must reproduce the above copyright michael@0: * notice, this list of conditions and the following disclaimer in the michael@0: * documentation and/or other materials provided with the distribution. michael@0: * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of michael@0: * its contributors may be used to endorse or promote products derived michael@0: * from this software without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY michael@0: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED michael@0: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE michael@0: * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY michael@0: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES michael@0: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; michael@0: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND michael@0: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT michael@0: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF michael@0: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: */ michael@0: michael@0: #ifndef DynamicsCompressorKernel_h michael@0: #define DynamicsCompressorKernel_h michael@0: michael@0: #include "nsTArray.h" michael@0: #include "nsAutoPtr.h" michael@0: #include "mozilla/MemoryReporting.h" michael@0: michael@0: namespace WebCore { michael@0: michael@0: class DynamicsCompressorKernel { michael@0: public: michael@0: DynamicsCompressorKernel(float sampleRate, unsigned numberOfChannels); michael@0: michael@0: void setNumberOfChannels(unsigned); michael@0: michael@0: // Performs stereo-linked compression. michael@0: void process(float* sourceChannels[], michael@0: float* destinationChannels[], michael@0: unsigned numberOfChannels, michael@0: unsigned framesToProcess, michael@0: michael@0: float dbThreshold, michael@0: float dbKnee, michael@0: float ratio, michael@0: float attackTime, michael@0: float releaseTime, michael@0: float preDelayTime, michael@0: float dbPostGain, michael@0: float effectBlend, michael@0: michael@0: float releaseZone1, michael@0: float releaseZone2, michael@0: float releaseZone3, michael@0: float releaseZone4 michael@0: ); michael@0: michael@0: void reset(); michael@0: michael@0: unsigned latencyFrames() const { return m_lastPreDelayFrames; } michael@0: michael@0: float sampleRate() const { return m_sampleRate; } michael@0: michael@0: float meteringGain() const { return m_meteringGain; } michael@0: michael@0: size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; michael@0: michael@0: protected: michael@0: float m_sampleRate; michael@0: michael@0: float m_detectorAverage; michael@0: float m_compressorGain; michael@0: michael@0: // Metering michael@0: float m_meteringReleaseK; michael@0: float m_meteringGain; michael@0: michael@0: // Lookahead section. michael@0: enum { MaxPreDelayFrames = 1024 }; michael@0: enum { MaxPreDelayFramesMask = MaxPreDelayFrames - 1 }; michael@0: enum { DefaultPreDelayFrames = 256 }; // setPreDelayTime() will override this initial value michael@0: unsigned m_lastPreDelayFrames; michael@0: void setPreDelayTime(float); michael@0: michael@0: nsTArray > m_preDelayBuffers; michael@0: int m_preDelayReadIndex; michael@0: int m_preDelayWriteIndex; michael@0: michael@0: float m_maxAttackCompressionDiffDb; michael@0: michael@0: // Static compression curve. michael@0: float kneeCurve(float x, float k); michael@0: float saturate(float x, float k); michael@0: float slopeAt(float x, float k); michael@0: float kAtSlope(float desiredSlope); michael@0: michael@0: float updateStaticCurveParameters(float dbThreshold, float dbKnee, float ratio); michael@0: michael@0: // Amount of input change in dB required for 1 dB of output change. michael@0: // This applies to the portion of the curve above m_kneeThresholdDb (see below). michael@0: float m_ratio; michael@0: float m_slope; // Inverse ratio. michael@0: michael@0: // The input to output change below the threshold is linear 1:1. michael@0: float m_linearThreshold; michael@0: float m_dbThreshold; michael@0: michael@0: // m_dbKnee is the number of dB above the threshold before we enter the "ratio" portion of the curve. michael@0: // m_kneeThresholdDb = m_dbThreshold + m_dbKnee michael@0: // The portion between m_dbThreshold and m_kneeThresholdDb is the "soft knee" portion of the curve michael@0: // which transitions smoothly from the linear portion to the ratio portion. michael@0: float m_dbKnee; michael@0: float m_kneeThreshold; michael@0: float m_kneeThresholdDb; michael@0: float m_ykneeThresholdDb; michael@0: michael@0: // Internal parameter for the knee portion of the curve. michael@0: float m_K; michael@0: }; michael@0: michael@0: } // namespace WebCore michael@0: michael@0: #endif // DynamicsCompressorKernel_h