locked
Audio Compression RRS feed

  • Question

  • I want a audio Compression Algorithm that perform best Audio Compress technique.pls help me
    Saturday, January 19, 2013 9:21 AM

Answers

  • this is my Compression

                                                      

    // based on SimpleComp v1.10 © 2006, ChunkWare Music Software, OPEN-SOURCE
    using System;
    using NAudio.Utils;

    namespace NAudio.Dsp
    {
        class SimpleCompressor : AttRelEnvelope
        {
            // transfer function
       private double threshdB; // threshold (dB)
       private double ratio; // ratio (compression: < 1 ; expansion: > 1)
            private double makeUpGain;


       // runtime variables
       private double envdB; // over-threshold envelope (dB)

            public SimpleCompressor(double attackTime, double releaseTime, double sampleRate)
                : base(attackTime, releaseTime, sampleRate)
            {
                this.threshdB = 0.0;
                this.ratio = 1.0;
                this.makeUpGain = 0.0;
                this.envdB = DC_OFFSET;
            }

            public SimpleCompressor()
                : base(10.0, 10.0, 44100.0)
            {
                this.threshdB = 0.0;
                this.ratio = 1.0;
                this.makeUpGain = 0.0;
                this.envdB = DC_OFFSET;
            }

            public double MakeUpGain
            {
                get { return makeUpGain; }
                set { makeUpGain = value; }
            }

            public double Threshold 
            {
                get { return threshdB; }
                set { threshdB = value; }
            }

            public double Ratio
            {
                get { return ratio; }
                set { ratio = value; }
            }

            // call before runtime (in resume())
            public void InitRuntime()
            {
                this.envdB = DC_OFFSET;
            }

            // // compressor runtime process
            public void Process(ref double in1, ref double in2)
            {
                // sidechain

                // rectify input
                double cv = 0.0;
                double rect1 = Math.Abs(in1); // n.b. was fabs
                double rect2 = Math.Abs(in2); // n.b. was fabs

                // if desired, one could use another EnvelopeDetector to smooth
                // the rectified signal.

                double link = Math.Max(rect1, rect2); // link channels with greater of 2

                link += DC_OFFSET; // add DC offset to avoid log( 0 )
                double keydB = Decibels.LinearToDecibels(link); // convert linear -> dB

                // threshold
                double overdB = keydB - threshdB; // delta over threshold
                if (overdB < 0.0)
                    overdB = 0.0;

                // attack/release

                overdB += DC_OFFSET; // add DC offset to avoid denormal

                Run(overdB, ref envdB); // run attack/release envelope

                overdB = envdB - DC_OFFSET; // subtract DC offset

                // Regarding the DC offset: In this case, since the offset is added before 
                // the attack/release processes, the envelope will never fall below the offset,
                // thereby avoiding denormals. However, to prevent the offset from causing
                // constant gain reduction, we must subtract it from the envelope, yielding
                // a minimum value of 0dB.

                // transfer function
                if (MakeUpGain <= 10.0f)
                {

                    double gr = overdB * (1 / ratio - 1.0); // gain reduction (dB)
                    gr = Decibels.DecibelsToLinear(gr) * Decibels.DecibelsToLinear(makeUpGain); // convert dB -> linear gr = overdB * (1 / ratio - 1.0); // gain reduction (dB)
                    // output gain
                    in1 *= gr; // apply gain reduction to input
                    in2 *= gr; 

                }
                else
                {
                    double gr = overdB * (1 / ratio - 1.0); // gain reduction (dB)
                    in1 *= gr; // apply gain reduction to input
                    in2 *= gr; 

                }
            }
        }
    }

    and Tried to Apply Audiocity this method      

    ///////////////////////////////////////////////////////////////////////////
    //
    // "Investigation in Dynamic Range Compression" - MSc Project
    // Copyright 2009, Michael Massberg
    // michael@massberg.org
    //
    ///////////////////////////////////////////////////////////////////////////


    #include "compressor.h"


    ///////////////////////////////////////////////////////////////////////////


    AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {
    return new Compressor(audioMaster);
    }


    ///////////////////////////////////////////////////////////////////////////


    Compressor::Compressor(audioMasterCallback audioMaster)
     : AudioEffectX(audioMaster, 1, kParamCount) {

    setUniqueID(CCONST('c', 'm', 'p', 'r'));
    setNumInputs(2);
    setNumOutputs(2);
    canProcessReplacing();
    setEditor(new CompressorEditor(this));

    vst_strncpy(programName, "Default", kVstMaxProgNameLen);

    for(VstInt32 i=0; i<kParamCount; i++) {
    setParameter(i, getParameterDefault(i));
    }

    DECLARE_VST_DEPRECATED(canMono) (true);

    #if !ENABLEPRESETS
    programsAreChunks();
    #endif

    initialize();
    }


    Compressor::~Compressor() { }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::initialize() {
    double fs = getSampleRate();
    rampCoeff = onePoleCoeff(fs, 0.05);
    }


    ///////////////////////////////////////////////////////////////////////////


    #if !ENABLEPRESETS

    VstInt32 Compressor::getChunk(void **data, bool isPreset) {
    static char buffer[32];;
    memset(buffer, 0, 32);
    *data = buffer;
    return 32;
    }


    VstInt32 Compressor::setChunk(void *data, VstInt32 byteSize, bool isPreset) {
    for(VstInt32 i=0; i<kParamCount; i++) {
    setParameter(i, getParameterDefault(i));
    }
    return 1;
    }

    #endif


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::setParameter(VstInt32 index, float value) {
    params[index] = value;
    double fs = getSampleRate();

    switch(index) {
    case kParamThreshold: logThreshold[kTarget] = log(pow(10.0, value * -MAXGAINDB / 20.0)); break;
    case kParamRatio: slope = -value; break;
    case kParamKneeWidth: logKneeWidth = log(pow(10.0, value * MAXGAINDB / 20.0)); break;
    case kParamGain: logGain[kTarget] = log(pow(10.0, value * MAXGAINDB / 20.0)); break;

    case kParamAttack:
    attackTime = PARAM2LOG(value, MINATTACKTIME, MAXATTACKTIME);
    attackCoeff = onePoleCoeff(fs, attackTime);
    break;

    case kParamRelease:
    releaseTime = PARAM2LOG(value, MINRELEASETIME, MAXRELEASETIME);
    releaseCoeff = onePoleCoeff(fs, releaseTime);
    break;

    case kParamActive: active = (value >= 0.5f); break;
    case kParamAutoKnee: autoKnee = (value >= 0.5f); break;
    case kParamAutoGain: autoGain = (value >= 0.5f); break;
    case kParamAutoAttack: autoAttack = (value >= 0.5f); break;
    case kParamAutoRelease: autoRelease = (value >= 0.5f); break;

    case kParamMetaKneeMult:
    metaKneeMult = PARAM2LIN(value, MINKNEEMULT, MAXKNEEMULT);
    break;

    case kParamMetaMaxAttack:
    metaMaxAttackTime = PARAM2LOG(value, MINATTACKTIME, MAXATTACKTIME);
    break;

    case kParamMetaMaxRelease:
    metaMaxReleaseTime = PARAM2LOG(value, MINRELEASETIME, MAXRELEASETIME);
    break;

    case kParamMetaCrest:
    metaCrestTime = PARAM2LOG(value, MINCRESTTIME, MAXCRESTTIME);
    metaCrestCoeff = onePoleCoeff(fs, metaCrestTime);
    break;

    case kParamMetaAdapt:
    metaAdaptTime = PARAM2LOG(value, MINADAPTTIME, MAXADAPTTIME);
    metaAdaptCoeff = onePoleCoeff(fs, metaAdaptTime);
    break;

    case kParamMetaNoClipping: metaNoClipping = (value >= 0.5f); break;
    }

    if(editor) {
    ((AEffGUIEditor*) editor)->setParameter(index, value);
    }
    }


    float Compressor::getParameter(VstInt32 index) {
    return params[index];
    }


    float Compressor::getParameterDefault(VstInt32 index) {
    switch(index) {
    case kParamActive: return 1.f;
    case kParamThreshold: return 0.f;
    case kParamRatio: return 0.f;
    case kParamGain: return 0.f;
    case kParamAttack: return (float) LOG2PARAM(0.005, MINATTACKTIME, MAXATTACKTIME);
    case kParamRelease: return (float) LOG2PARAM(0.05, MINRELEASETIME, MAXRELEASETIME);

    case kParamAutoAttack:
    case kParamAutoRelease:
    case kParamAutoKnee:
    case kParamAutoGain:
    return 1.f;

    case kParamMetaKneeMult: return (float) LIN2PARAM(2.0, MINKNEEMULT, MAXKNEEMULT);
    case kParamMetaMaxAttack: return (float) LOG2PARAM(0.08, MINATTACKTIME, MAXATTACKTIME);
    case kParamMetaMaxRelease: return (float) LOG2PARAM(1.0, MINRELEASETIME, MAXRELEASETIME);
    case kParamMetaCrest: return (float) LOG2PARAM(0.2, MINCRESTTIME, MAXCRESTTIME);
    case kParamMetaAdapt: return (float) LOG2PARAM(2.5, MINADAPTTIME, MAXADAPTTIME);
    case kParamMetaNoClipping: return 1.f;
    }
    return 0.f;
    }


    float Compressor::getParameterFromString(VstInt32 index, char *text) {
    double x = atof(text);
    switch(index) {
    case kParamThreshold: return (float) CLAMP(fabs(x) / MAXGAINDB, 0.0, 1.0);
    case kParamRatio: return (float) (1.0 - 1.0 / CLAMP(fabs(x), 1.0, 100.0));
    case kParamKneeWidth: return (float) CLAMP(fabs(x) / MAXGAINDB, 0.0, 1.0);
    case kParamGain: return (float) CLAMP(fabs(x) / MAXGAINDB, 0.0, 1.0);
    case kParamAttack: return (float) LOG2PARAM(CLAMP(fabs(x) / 1000.0, MINATTACKTIME, MAXATTACKTIME), MINATTACKTIME, MAXATTACKTIME);
    case kParamRelease: return (float) LOG2PARAM(CLAMP(fabs(x) / 1000.0, MINRELEASETIME, MAXRELEASETIME), MINRELEASETIME, MAXRELEASETIME);
    }
    return getParameter(index);
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::getParameterName(VstInt32 index, char *label) {
    switch(index) {
    case kParamActive: vst_strncpy(label, "Active", kVstMaxParamStrLen); return;
    case kParamThreshold: vst_strncpy(label, "Thresh", kVstMaxParamStrLen); return;
    case kParamKneeWidth: vst_strncpy(label, "Width", kVstMaxParamStrLen); return;
    case kParamAutoKnee: vst_strncpy(label, "AutoKnee", kVstMaxParamStrLen); return;
    case kParamGain: vst_strncpy(label, "Gain", kVstMaxParamStrLen); return;
    case kParamAutoGain: vst_strncpy(label, "AutoGain", kVstMaxParamStrLen); return;
    case kParamRatio: vst_strncpy(label, "Ratio", kVstMaxParamStrLen); return;
    case kParamAttack: vst_strncpy(label, "Attack", kVstMaxParamStrLen); return;
    case kParamAutoAttack: vst_strncpy(label, "AutoAtt", kVstMaxParamStrLen); return;
    case kParamRelease: vst_strncpy(label, "Release", kVstMaxParamStrLen); return;
    case kParamAutoRelease: vst_strncpy(label, "AutoRel", kVstMaxParamStrLen); return;

    case kParamMetaKneeMult: vst_strncpy(label, "KneeMult", kVstMaxParamStrLen); return;
    case kParamMetaMaxAttack: vst_strncpy(label, "MaxAtt", kVstMaxParamStrLen); return;
    case kParamMetaMaxRelease: vst_strncpy(label, "MaxRel", kVstMaxParamStrLen); return;
    case kParamMetaCrest: vst_strncpy(label, "Crest", kVstMaxParamStrLen); return;
    case kParamMetaAdapt: vst_strncpy(label, "Adapt", kVstMaxParamStrLen); return;
    case kParamMetaNoClipping: vst_strncpy(label, "NoClip", kVstMaxParamStrLen); return;
    }
    vst_strncpy(label, "", kVstMaxParamStrLen); 
    }


    void Compressor::getParameterDisplay(VstInt32 index, char *text) {
    switch(index) {
    case kParamRatio:
    if(slope > -0.99) {
    float2string((float) (1.0 / (1.0 + slope)), text, kVstMaxParamStrLen);
    vst_strncat(text, ":1", kVstMaxParamStrLen);
    }
    else {
    vst_strncpy(text, "oo:1", kVstMaxParamStrLen);
    }
    return;

    case kParamThreshold: dB2string((float) exp(logThreshold[kTarget]), text, kVstMaxParamStrLen); return;
    case kParamGain: dB2string((float) exp(logGain[kTarget]), text, kVstMaxParamStrLen); return;
    case kParamKneeWidth: dB2string((float) exp(logKneeWidth), text, kVstMaxParamStrLen); return;
    case kParamAttack: float2string((float) (attackTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamRelease: float2string((float) (releaseTime * 1000.0), text, kVstMaxParamStrLen); return;

    case kParamMetaKneeMult: float2string((float) metaKneeMult, text, kVstMaxParamStrLen); return;
    case kParamMetaMaxAttack: float2string((float) (metaMaxAttackTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamMetaMaxRelease: float2string((float) (metaMaxReleaseTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamMetaCrest: float2string((float) (metaCrestTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamMetaAdapt: float2string((float) (metaAdaptTime * 1000.0), text, kVstMaxParamStrLen); return;
    }
    vst_strncpy(text, (getParameter(index) >= 0.5f)?"On":"Off", kVstMaxParamStrLen);
    }


    void Compressor::getParameterLabel(VstInt32 index, char *label) {
    switch(index) {
    case kParamThreshold:
    case kParamGain:
    case kParamKneeWidth:
    vst_strncpy(label, "dB", kVstMaxParamStrLen); 
    return;

    case kParamAttack:
    case kParamRelease:
    case kParamMetaMaxAttack:
    case kParamMetaMaxRelease:
    case kParamMetaCrest:
    case kParamMetaAdapt:
    vst_strncpy(label, "ms", kVstMaxParamStrLen); 
    return;
    }
    vst_strncpy(label, "", kVstMaxParamStrLen); 
    }


    ///////////////////////////////////////////////////////////////////////////


    float Compressor::getMeter(VstInt32 index) {
    switch(index) {
    case kMeterGR:
    if(active) {
    return (float) CLAMP((-cvAttack - MINMETERLOG) / (0.0 - MINMETERLOG), 0.0, 1.0);
    }
    return 1.f;
    }
    return 0.f;
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::getProgramName(char *text) {
    vst_strncpy(text, programName, kVstMaxProgNameLen);
    }


    void Compressor::setProgramName(char* name) {
    vst_strncpy(programName, name, kVstMaxProgNameLen);
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::setSampleRate(float sampleRate) {
    AudioEffectX::setSampleRate(sampleRate);
    for(int j=0; j<kParamCount; j++) {
    setParameter(j, getParameter(j));
    }
    initialize();
    }


    void Compressor::setProgram(VstInt32 program) {
    AudioEffectX::setProgram(program);
    for(int j=0; j<kParamCount; j++) {
    setParameter(j, getParameter(j));
    }
    }


    ///////////////////////////////////////////////////////////////////////////


    bool Compressor::getEffectName(char *name) {
    vst_strncpy(name, "Auto Compressor", kVstMaxEffectNameLen);
    return true;
    }


    bool Compressor::getProductString (char *text) {
    vst_strncpy(text, "VST Plug-Ins", kVstMaxProductStrLen);
    return true;
    }


    bool Compressor::getVendorString (char *text) {
    vst_strncpy(text, "Michael Massberg", kVstMaxVendorStrLen);
    return true;
    }


    VstInt32 Compressor::getVendorVersion() {
    return 1000;
    }


    VstPlugCategory Compressor::getPlugCategory () {
    return kPlugCategEffect;
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::resume() {
    crestRms = crestPeak = MINVAL;
    cvSmooth = cvAttack = cvRelease = 0.0;
    logThreshold[kCurrent] = logThreshold[kTarget];
    logGain[kCurrent] = logGain[kTarget];
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) {
    float *inBufferL = inputs[0];
    float *inBufferR = inputs[1];
    float *outBufferL = outputs[0];
    float *outBufferR = outputs[1];

    while(--sampleFrames >= 0) {
    // Process
    float inL = *inBufferL++;
    float inR = *inBufferR++;

    float absL = ABS(inL);
    float absR = ABS(inR);
    float maxLR = MAX(absL, absR);

    float mult = (float) processSidechain(maxLR);
    float outL = inL;
    float outR = inR;

    if(active) {
    outL *= mult;
    outR *= mult;
    }

    *outBufferL++ = outL;
    *outBufferR++ = outR;

    // Ramp parameters
    logThreshold[kCurrent] = MIX(logThreshold[kTarget], logThreshold[kCurrent], rampCoeff);
    logGain[kCurrent] = MIX(logGain[kTarget], logGain[kCurrent], rampCoeff);
    }

    // Kill denormals
    cvAttack = killDenormal(cvAttack);
    cvRelease = killDenormal(cvRelease);
    cvSmooth = killDenormal(cvSmooth);
    crestRms = killDenormal(crestRms);
    crestPeak = killDenormal(crestPeak);
    logThreshold[kCurrent] = killDenormal(logThreshold[kCurrent]);
    logGain[kCurrent] = killDenormal(logGain[kCurrent]);
    }


    FORCEINLINE double Compressor::processSidechain(double inAbs) {
    double fs = getSampleRate();

    // Square of crest factor
    double inSquare = MAX(SQUARE(inAbs), MINVAL);
    crestRms = MIX(inSquare, crestRms, metaCrestCoeff);
    crestPeak = MAX(MIX(inSquare, crestPeak, metaCrestCoeff), inSquare);
    double crestSquare = crestPeak / crestRms;

    // Attack and release coefficients
    double myAttackCoeff = attackCoeff;
    double myAttackTime = attackTime;
    if(autoAttack) {
    myAttackTime = 2.0 * metaMaxAttackTime / crestSquare;
    myAttackCoeff = onePoleCoeff(fs, myAttackTime);
    }

    double myReleaseCoeff = releaseCoeff;
    if(autoRelease) {
    double myReleaseTime = 2.0 * metaMaxReleaseTime / crestSquare;
    myReleaseCoeff = onePoleCoeff(fs, myReleaseTime - myAttackTime);
    }

    // Log conversion and overshoot
    double logIn = log(MAX(inAbs, MINVAL));
    double logOvershoot = logIn - logThreshold[kCurrent];

    // Set ratio/slope
    double mySlope = slope;
    if(autoKnee) { mySlope = -1.0; }

    // Set estimate for average CV
    double cvEstimate = logThreshold[kCurrent] * -mySlope / 2.0;

    // Set knee width
    double myLogWidth = logKneeWidth;
    if(autoKnee) { myLogWidth = MAX(-(cvSmooth + cvEstimate) * metaKneeMult, 0.0); }

    // Soft knee rectification
    double cv = 0.0;
    if(logOvershoot >= myLogWidth / 2.0) {
    cv = logOvershoot;
    }
    else if(logOvershoot > -myLogWidth / 2.0 && logOvershoot < myLogWidth / 2.0) {
    cv = 1.0 / (2.0 * myLogWidth) * SQUARE(logOvershoot + myLogWidth / 2.0);
    }

    // Multiply by negative slope for positive CV
    cv *= -mySlope;

    // Release and Attack
    cvRelease = MAX(cv, MIX(cv, cvRelease, myReleaseCoeff));
    cvAttack = MIX(cvRelease, cvAttack, myAttackCoeff);

    // Invert CV again
    cv = -cvAttack;

    // Smooth CV
    cvSmooth = MIX(cv - cvEstimate, cvSmooth, metaAdaptCoeff);

    // Make-up gain
    if(autoGain) {
    // Check for clipping
    if(metaNoClipping && logIn + cv - (cvSmooth + cvEstimate) > MAXCLIPLOG) {
    cvSmooth = logIn + cv - cvEstimate - MAXCLIPLOG;
    }

    // Apply automatic gain
    cv -= cvSmooth + cvEstimate;
    }
    else {
    // Apply static gain
    cv += logGain[kCurrent];
    }

    // VCA
    return exp(cv);
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::float2string (float value, char* text, VstInt32 maxLen) {
    bool sign = false;
    long digits = 2;

    char buf[9];
    char* ptr = buf + 8;
    *ptr-- = '\0';

    // Rectify and round
    double dval = value;
    if(dval < 0.0) { dval = -dval; }
    dval += pow(10.0, -digits) * 0.5;

    // Convert integer part
    long count = 0;
    double temp = floor(dval);
    do {
    *ptr-- = '0' + (char) ((long) fmod(temp, 10.0));
    temp /= 10.0; count++;
    } while(temp >= 1.0 && count < 7);

    if(temp < 1.0) {
    // Add sign
    if(value < 0.f) {
    *ptr-- = '-';
    count++;
    }
    else if(sign && value > 0.f) {
    *ptr-- = '+';
    count++;
    }

    // Copy integer part
    vst_strncpy(text, ptr + 1, maxLen);

    if(maxLen - count > 1 && digits > 0) {
    // Convert fractional part
    char* ptr = buf + 7;
    count = 0;

    long maxdigits = 7;
    if(maxdigits > digits) { maxdigits = digits; }

    temp = fmod(dval, 1.0) * pow(10.0, maxdigits);
    while(count < maxdigits) {
    *ptr-- = '0' + (char) ((long) fmod(temp, 10.0));
    temp /= 10.0; count++;
    }

    // Add point
    *ptr = '.';

    // Copy fractional part
    vst_strncat(text, ptr, maxLen);
    }
    }
    else {
    // Value was too big
    if(value < 0.f) {
    vst_strncpy(text, "-oo", maxLen);
    }
    else {
    vst_strncpy(text, sign?"+oo":"oo", maxLen);
    }
    }
    }

    How this i s Possible pls send .

    Mainly wathchin on Process Method

    • Marked as answer by Sudipda Wednesday, January 23, 2013 11:58 AM
    Tuesday, January 22, 2013 7:25 AM

All replies

  • Have you taken a look at Ogg Vorbis?

    http://xiph.org/vorbis/

    You could start there to see if fits your requirements.


    • Edited by Andreas Johansson Saturday, January 19, 2013 12:21 PM Link is a link.
    • Proposed as answer by Mike Feng Monday, January 21, 2013 5:53 AM
    • Marked as answer by Sudipda Monday, January 21, 2013 8:42 AM
    • Unmarked as answer by Sudipda Monday, January 21, 2013 8:43 AM
    • Unproposed as answer by Sudipda Monday, January 21, 2013 8:43 AM
    Saturday, January 19, 2013 12:21 PM
  • not good enough.
    Monday, January 21, 2013 9:24 AM
  • not good enough.
    Maybe you can try to specify a bit what it is you are looking for and possibly what my suggestion is lacking.
    Monday, January 21, 2013 11:49 AM
  • this is my Compression

                                                      

    // based on SimpleComp v1.10 © 2006, ChunkWare Music Software, OPEN-SOURCE
    using System;
    using NAudio.Utils;

    namespace NAudio.Dsp
    {
        class SimpleCompressor : AttRelEnvelope
        {
            // transfer function
       private double threshdB; // threshold (dB)
       private double ratio; // ratio (compression: < 1 ; expansion: > 1)
            private double makeUpGain;


       // runtime variables
       private double envdB; // over-threshold envelope (dB)

            public SimpleCompressor(double attackTime, double releaseTime, double sampleRate)
                : base(attackTime, releaseTime, sampleRate)
            {
                this.threshdB = 0.0;
                this.ratio = 1.0;
                this.makeUpGain = 0.0;
                this.envdB = DC_OFFSET;
            }

            public SimpleCompressor()
                : base(10.0, 10.0, 44100.0)
            {
                this.threshdB = 0.0;
                this.ratio = 1.0;
                this.makeUpGain = 0.0;
                this.envdB = DC_OFFSET;
            }

            public double MakeUpGain
            {
                get { return makeUpGain; }
                set { makeUpGain = value; }
            }

            public double Threshold 
            {
                get { return threshdB; }
                set { threshdB = value; }
            }

            public double Ratio
            {
                get { return ratio; }
                set { ratio = value; }
            }

            // call before runtime (in resume())
            public void InitRuntime()
            {
                this.envdB = DC_OFFSET;
            }

            // // compressor runtime process
            public void Process(ref double in1, ref double in2)
            {
                // sidechain

                // rectify input
                double cv = 0.0;
                double rect1 = Math.Abs(in1); // n.b. was fabs
                double rect2 = Math.Abs(in2); // n.b. was fabs

                // if desired, one could use another EnvelopeDetector to smooth
                // the rectified signal.

                double link = Math.Max(rect1, rect2); // link channels with greater of 2

                link += DC_OFFSET; // add DC offset to avoid log( 0 )
                double keydB = Decibels.LinearToDecibels(link); // convert linear -> dB

                // threshold
                double overdB = keydB - threshdB; // delta over threshold
                if (overdB < 0.0)
                    overdB = 0.0;

                // attack/release

                overdB += DC_OFFSET; // add DC offset to avoid denormal

                Run(overdB, ref envdB); // run attack/release envelope

                overdB = envdB - DC_OFFSET; // subtract DC offset

                // Regarding the DC offset: In this case, since the offset is added before 
                // the attack/release processes, the envelope will never fall below the offset,
                // thereby avoiding denormals. However, to prevent the offset from causing
                // constant gain reduction, we must subtract it from the envelope, yielding
                // a minimum value of 0dB.

                // transfer function
                if (MakeUpGain <= 10.0f)
                {

                    double gr = overdB * (1 / ratio - 1.0); // gain reduction (dB)
                    gr = Decibels.DecibelsToLinear(gr) * Decibels.DecibelsToLinear(makeUpGain); // convert dB -> linear gr = overdB * (1 / ratio - 1.0); // gain reduction (dB)
                    // output gain
                    in1 *= gr; // apply gain reduction to input
                    in2 *= gr; 

                }
                else
                {
                    double gr = overdB * (1 / ratio - 1.0); // gain reduction (dB)
                    in1 *= gr; // apply gain reduction to input
                    in2 *= gr; 

                }
            }
        }
    }

    and Tried to Apply Audiocity this method      

    ///////////////////////////////////////////////////////////////////////////
    //
    // "Investigation in Dynamic Range Compression" - MSc Project
    // Copyright 2009, Michael Massberg
    // michael@massberg.org
    //
    ///////////////////////////////////////////////////////////////////////////


    #include "compressor.h"


    ///////////////////////////////////////////////////////////////////////////


    AudioEffect* createEffectInstance(audioMasterCallback audioMaster) {
    return new Compressor(audioMaster);
    }


    ///////////////////////////////////////////////////////////////////////////


    Compressor::Compressor(audioMasterCallback audioMaster)
     : AudioEffectX(audioMaster, 1, kParamCount) {

    setUniqueID(CCONST('c', 'm', 'p', 'r'));
    setNumInputs(2);
    setNumOutputs(2);
    canProcessReplacing();
    setEditor(new CompressorEditor(this));

    vst_strncpy(programName, "Default", kVstMaxProgNameLen);

    for(VstInt32 i=0; i<kParamCount; i++) {
    setParameter(i, getParameterDefault(i));
    }

    DECLARE_VST_DEPRECATED(canMono) (true);

    #if !ENABLEPRESETS
    programsAreChunks();
    #endif

    initialize();
    }


    Compressor::~Compressor() { }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::initialize() {
    double fs = getSampleRate();
    rampCoeff = onePoleCoeff(fs, 0.05);
    }


    ///////////////////////////////////////////////////////////////////////////


    #if !ENABLEPRESETS

    VstInt32 Compressor::getChunk(void **data, bool isPreset) {
    static char buffer[32];;
    memset(buffer, 0, 32);
    *data = buffer;
    return 32;
    }


    VstInt32 Compressor::setChunk(void *data, VstInt32 byteSize, bool isPreset) {
    for(VstInt32 i=0; i<kParamCount; i++) {
    setParameter(i, getParameterDefault(i));
    }
    return 1;
    }

    #endif


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::setParameter(VstInt32 index, float value) {
    params[index] = value;
    double fs = getSampleRate();

    switch(index) {
    case kParamThreshold: logThreshold[kTarget] = log(pow(10.0, value * -MAXGAINDB / 20.0)); break;
    case kParamRatio: slope = -value; break;
    case kParamKneeWidth: logKneeWidth = log(pow(10.0, value * MAXGAINDB / 20.0)); break;
    case kParamGain: logGain[kTarget] = log(pow(10.0, value * MAXGAINDB / 20.0)); break;

    case kParamAttack:
    attackTime = PARAM2LOG(value, MINATTACKTIME, MAXATTACKTIME);
    attackCoeff = onePoleCoeff(fs, attackTime);
    break;

    case kParamRelease:
    releaseTime = PARAM2LOG(value, MINRELEASETIME, MAXRELEASETIME);
    releaseCoeff = onePoleCoeff(fs, releaseTime);
    break;

    case kParamActive: active = (value >= 0.5f); break;
    case kParamAutoKnee: autoKnee = (value >= 0.5f); break;
    case kParamAutoGain: autoGain = (value >= 0.5f); break;
    case kParamAutoAttack: autoAttack = (value >= 0.5f); break;
    case kParamAutoRelease: autoRelease = (value >= 0.5f); break;

    case kParamMetaKneeMult:
    metaKneeMult = PARAM2LIN(value, MINKNEEMULT, MAXKNEEMULT);
    break;

    case kParamMetaMaxAttack:
    metaMaxAttackTime = PARAM2LOG(value, MINATTACKTIME, MAXATTACKTIME);
    break;

    case kParamMetaMaxRelease:
    metaMaxReleaseTime = PARAM2LOG(value, MINRELEASETIME, MAXRELEASETIME);
    break;

    case kParamMetaCrest:
    metaCrestTime = PARAM2LOG(value, MINCRESTTIME, MAXCRESTTIME);
    metaCrestCoeff = onePoleCoeff(fs, metaCrestTime);
    break;

    case kParamMetaAdapt:
    metaAdaptTime = PARAM2LOG(value, MINADAPTTIME, MAXADAPTTIME);
    metaAdaptCoeff = onePoleCoeff(fs, metaAdaptTime);
    break;

    case kParamMetaNoClipping: metaNoClipping = (value >= 0.5f); break;
    }

    if(editor) {
    ((AEffGUIEditor*) editor)->setParameter(index, value);
    }
    }


    float Compressor::getParameter(VstInt32 index) {
    return params[index];
    }


    float Compressor::getParameterDefault(VstInt32 index) {
    switch(index) {
    case kParamActive: return 1.f;
    case kParamThreshold: return 0.f;
    case kParamRatio: return 0.f;
    case kParamGain: return 0.f;
    case kParamAttack: return (float) LOG2PARAM(0.005, MINATTACKTIME, MAXATTACKTIME);
    case kParamRelease: return (float) LOG2PARAM(0.05, MINRELEASETIME, MAXRELEASETIME);

    case kParamAutoAttack:
    case kParamAutoRelease:
    case kParamAutoKnee:
    case kParamAutoGain:
    return 1.f;

    case kParamMetaKneeMult: return (float) LIN2PARAM(2.0, MINKNEEMULT, MAXKNEEMULT);
    case kParamMetaMaxAttack: return (float) LOG2PARAM(0.08, MINATTACKTIME, MAXATTACKTIME);
    case kParamMetaMaxRelease: return (float) LOG2PARAM(1.0, MINRELEASETIME, MAXRELEASETIME);
    case kParamMetaCrest: return (float) LOG2PARAM(0.2, MINCRESTTIME, MAXCRESTTIME);
    case kParamMetaAdapt: return (float) LOG2PARAM(2.5, MINADAPTTIME, MAXADAPTTIME);
    case kParamMetaNoClipping: return 1.f;
    }
    return 0.f;
    }


    float Compressor::getParameterFromString(VstInt32 index, char *text) {
    double x = atof(text);
    switch(index) {
    case kParamThreshold: return (float) CLAMP(fabs(x) / MAXGAINDB, 0.0, 1.0);
    case kParamRatio: return (float) (1.0 - 1.0 / CLAMP(fabs(x), 1.0, 100.0));
    case kParamKneeWidth: return (float) CLAMP(fabs(x) / MAXGAINDB, 0.0, 1.0);
    case kParamGain: return (float) CLAMP(fabs(x) / MAXGAINDB, 0.0, 1.0);
    case kParamAttack: return (float) LOG2PARAM(CLAMP(fabs(x) / 1000.0, MINATTACKTIME, MAXATTACKTIME), MINATTACKTIME, MAXATTACKTIME);
    case kParamRelease: return (float) LOG2PARAM(CLAMP(fabs(x) / 1000.0, MINRELEASETIME, MAXRELEASETIME), MINRELEASETIME, MAXRELEASETIME);
    }
    return getParameter(index);
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::getParameterName(VstInt32 index, char *label) {
    switch(index) {
    case kParamActive: vst_strncpy(label, "Active", kVstMaxParamStrLen); return;
    case kParamThreshold: vst_strncpy(label, "Thresh", kVstMaxParamStrLen); return;
    case kParamKneeWidth: vst_strncpy(label, "Width", kVstMaxParamStrLen); return;
    case kParamAutoKnee: vst_strncpy(label, "AutoKnee", kVstMaxParamStrLen); return;
    case kParamGain: vst_strncpy(label, "Gain", kVstMaxParamStrLen); return;
    case kParamAutoGain: vst_strncpy(label, "AutoGain", kVstMaxParamStrLen); return;
    case kParamRatio: vst_strncpy(label, "Ratio", kVstMaxParamStrLen); return;
    case kParamAttack: vst_strncpy(label, "Attack", kVstMaxParamStrLen); return;
    case kParamAutoAttack: vst_strncpy(label, "AutoAtt", kVstMaxParamStrLen); return;
    case kParamRelease: vst_strncpy(label, "Release", kVstMaxParamStrLen); return;
    case kParamAutoRelease: vst_strncpy(label, "AutoRel", kVstMaxParamStrLen); return;

    case kParamMetaKneeMult: vst_strncpy(label, "KneeMult", kVstMaxParamStrLen); return;
    case kParamMetaMaxAttack: vst_strncpy(label, "MaxAtt", kVstMaxParamStrLen); return;
    case kParamMetaMaxRelease: vst_strncpy(label, "MaxRel", kVstMaxParamStrLen); return;
    case kParamMetaCrest: vst_strncpy(label, "Crest", kVstMaxParamStrLen); return;
    case kParamMetaAdapt: vst_strncpy(label, "Adapt", kVstMaxParamStrLen); return;
    case kParamMetaNoClipping: vst_strncpy(label, "NoClip", kVstMaxParamStrLen); return;
    }
    vst_strncpy(label, "", kVstMaxParamStrLen); 
    }


    void Compressor::getParameterDisplay(VstInt32 index, char *text) {
    switch(index) {
    case kParamRatio:
    if(slope > -0.99) {
    float2string((float) (1.0 / (1.0 + slope)), text, kVstMaxParamStrLen);
    vst_strncat(text, ":1", kVstMaxParamStrLen);
    }
    else {
    vst_strncpy(text, "oo:1", kVstMaxParamStrLen);
    }
    return;

    case kParamThreshold: dB2string((float) exp(logThreshold[kTarget]), text, kVstMaxParamStrLen); return;
    case kParamGain: dB2string((float) exp(logGain[kTarget]), text, kVstMaxParamStrLen); return;
    case kParamKneeWidth: dB2string((float) exp(logKneeWidth), text, kVstMaxParamStrLen); return;
    case kParamAttack: float2string((float) (attackTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamRelease: float2string((float) (releaseTime * 1000.0), text, kVstMaxParamStrLen); return;

    case kParamMetaKneeMult: float2string((float) metaKneeMult, text, kVstMaxParamStrLen); return;
    case kParamMetaMaxAttack: float2string((float) (metaMaxAttackTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamMetaMaxRelease: float2string((float) (metaMaxReleaseTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamMetaCrest: float2string((float) (metaCrestTime * 1000.0), text, kVstMaxParamStrLen); return;
    case kParamMetaAdapt: float2string((float) (metaAdaptTime * 1000.0), text, kVstMaxParamStrLen); return;
    }
    vst_strncpy(text, (getParameter(index) >= 0.5f)?"On":"Off", kVstMaxParamStrLen);
    }


    void Compressor::getParameterLabel(VstInt32 index, char *label) {
    switch(index) {
    case kParamThreshold:
    case kParamGain:
    case kParamKneeWidth:
    vst_strncpy(label, "dB", kVstMaxParamStrLen); 
    return;

    case kParamAttack:
    case kParamRelease:
    case kParamMetaMaxAttack:
    case kParamMetaMaxRelease:
    case kParamMetaCrest:
    case kParamMetaAdapt:
    vst_strncpy(label, "ms", kVstMaxParamStrLen); 
    return;
    }
    vst_strncpy(label, "", kVstMaxParamStrLen); 
    }


    ///////////////////////////////////////////////////////////////////////////


    float Compressor::getMeter(VstInt32 index) {
    switch(index) {
    case kMeterGR:
    if(active) {
    return (float) CLAMP((-cvAttack - MINMETERLOG) / (0.0 - MINMETERLOG), 0.0, 1.0);
    }
    return 1.f;
    }
    return 0.f;
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::getProgramName(char *text) {
    vst_strncpy(text, programName, kVstMaxProgNameLen);
    }


    void Compressor::setProgramName(char* name) {
    vst_strncpy(programName, name, kVstMaxProgNameLen);
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::setSampleRate(float sampleRate) {
    AudioEffectX::setSampleRate(sampleRate);
    for(int j=0; j<kParamCount; j++) {
    setParameter(j, getParameter(j));
    }
    initialize();
    }


    void Compressor::setProgram(VstInt32 program) {
    AudioEffectX::setProgram(program);
    for(int j=0; j<kParamCount; j++) {
    setParameter(j, getParameter(j));
    }
    }


    ///////////////////////////////////////////////////////////////////////////


    bool Compressor::getEffectName(char *name) {
    vst_strncpy(name, "Auto Compressor", kVstMaxEffectNameLen);
    return true;
    }


    bool Compressor::getProductString (char *text) {
    vst_strncpy(text, "VST Plug-Ins", kVstMaxProductStrLen);
    return true;
    }


    bool Compressor::getVendorString (char *text) {
    vst_strncpy(text, "Michael Massberg", kVstMaxVendorStrLen);
    return true;
    }


    VstInt32 Compressor::getVendorVersion() {
    return 1000;
    }


    VstPlugCategory Compressor::getPlugCategory () {
    return kPlugCategEffect;
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::resume() {
    crestRms = crestPeak = MINVAL;
    cvSmooth = cvAttack = cvRelease = 0.0;
    logThreshold[kCurrent] = logThreshold[kTarget];
    logGain[kCurrent] = logGain[kTarget];
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) {
    float *inBufferL = inputs[0];
    float *inBufferR = inputs[1];
    float *outBufferL = outputs[0];
    float *outBufferR = outputs[1];

    while(--sampleFrames >= 0) {
    // Process
    float inL = *inBufferL++;
    float inR = *inBufferR++;

    float absL = ABS(inL);
    float absR = ABS(inR);
    float maxLR = MAX(absL, absR);

    float mult = (float) processSidechain(maxLR);
    float outL = inL;
    float outR = inR;

    if(active) {
    outL *= mult;
    outR *= mult;
    }

    *outBufferL++ = outL;
    *outBufferR++ = outR;

    // Ramp parameters
    logThreshold[kCurrent] = MIX(logThreshold[kTarget], logThreshold[kCurrent], rampCoeff);
    logGain[kCurrent] = MIX(logGain[kTarget], logGain[kCurrent], rampCoeff);
    }

    // Kill denormals
    cvAttack = killDenormal(cvAttack);
    cvRelease = killDenormal(cvRelease);
    cvSmooth = killDenormal(cvSmooth);
    crestRms = killDenormal(crestRms);
    crestPeak = killDenormal(crestPeak);
    logThreshold[kCurrent] = killDenormal(logThreshold[kCurrent]);
    logGain[kCurrent] = killDenormal(logGain[kCurrent]);
    }


    FORCEINLINE double Compressor::processSidechain(double inAbs) {
    double fs = getSampleRate();

    // Square of crest factor
    double inSquare = MAX(SQUARE(inAbs), MINVAL);
    crestRms = MIX(inSquare, crestRms, metaCrestCoeff);
    crestPeak = MAX(MIX(inSquare, crestPeak, metaCrestCoeff), inSquare);
    double crestSquare = crestPeak / crestRms;

    // Attack and release coefficients
    double myAttackCoeff = attackCoeff;
    double myAttackTime = attackTime;
    if(autoAttack) {
    myAttackTime = 2.0 * metaMaxAttackTime / crestSquare;
    myAttackCoeff = onePoleCoeff(fs, myAttackTime);
    }

    double myReleaseCoeff = releaseCoeff;
    if(autoRelease) {
    double myReleaseTime = 2.0 * metaMaxReleaseTime / crestSquare;
    myReleaseCoeff = onePoleCoeff(fs, myReleaseTime - myAttackTime);
    }

    // Log conversion and overshoot
    double logIn = log(MAX(inAbs, MINVAL));
    double logOvershoot = logIn - logThreshold[kCurrent];

    // Set ratio/slope
    double mySlope = slope;
    if(autoKnee) { mySlope = -1.0; }

    // Set estimate for average CV
    double cvEstimate = logThreshold[kCurrent] * -mySlope / 2.0;

    // Set knee width
    double myLogWidth = logKneeWidth;
    if(autoKnee) { myLogWidth = MAX(-(cvSmooth + cvEstimate) * metaKneeMult, 0.0); }

    // Soft knee rectification
    double cv = 0.0;
    if(logOvershoot >= myLogWidth / 2.0) {
    cv = logOvershoot;
    }
    else if(logOvershoot > -myLogWidth / 2.0 && logOvershoot < myLogWidth / 2.0) {
    cv = 1.0 / (2.0 * myLogWidth) * SQUARE(logOvershoot + myLogWidth / 2.0);
    }

    // Multiply by negative slope for positive CV
    cv *= -mySlope;

    // Release and Attack
    cvRelease = MAX(cv, MIX(cv, cvRelease, myReleaseCoeff));
    cvAttack = MIX(cvRelease, cvAttack, myAttackCoeff);

    // Invert CV again
    cv = -cvAttack;

    // Smooth CV
    cvSmooth = MIX(cv - cvEstimate, cvSmooth, metaAdaptCoeff);

    // Make-up gain
    if(autoGain) {
    // Check for clipping
    if(metaNoClipping && logIn + cv - (cvSmooth + cvEstimate) > MAXCLIPLOG) {
    cvSmooth = logIn + cv - cvEstimate - MAXCLIPLOG;
    }

    // Apply automatic gain
    cv -= cvSmooth + cvEstimate;
    }
    else {
    // Apply static gain
    cv += logGain[kCurrent];
    }

    // VCA
    return exp(cv);
    }


    ///////////////////////////////////////////////////////////////////////////


    void Compressor::float2string (float value, char* text, VstInt32 maxLen) {
    bool sign = false;
    long digits = 2;

    char buf[9];
    char* ptr = buf + 8;
    *ptr-- = '\0';

    // Rectify and round
    double dval = value;
    if(dval < 0.0) { dval = -dval; }
    dval += pow(10.0, -digits) * 0.5;

    // Convert integer part
    long count = 0;
    double temp = floor(dval);
    do {
    *ptr-- = '0' + (char) ((long) fmod(temp, 10.0));
    temp /= 10.0; count++;
    } while(temp >= 1.0 && count < 7);

    if(temp < 1.0) {
    // Add sign
    if(value < 0.f) {
    *ptr-- = '-';
    count++;
    }
    else if(sign && value > 0.f) {
    *ptr-- = '+';
    count++;
    }

    // Copy integer part
    vst_strncpy(text, ptr + 1, maxLen);

    if(maxLen - count > 1 && digits > 0) {
    // Convert fractional part
    char* ptr = buf + 7;
    count = 0;

    long maxdigits = 7;
    if(maxdigits > digits) { maxdigits = digits; }

    temp = fmod(dval, 1.0) * pow(10.0, maxdigits);
    while(count < maxdigits) {
    *ptr-- = '0' + (char) ((long) fmod(temp, 10.0));
    temp /= 10.0; count++;
    }

    // Add point
    *ptr = '.';

    // Copy fractional part
    vst_strncat(text, ptr, maxLen);
    }
    }
    else {
    // Value was too big
    if(value < 0.f) {
    vst_strncpy(text, "-oo", maxLen);
    }
    else {
    vst_strncpy(text, sign?"+oo":"oo", maxLen);
    }
    }
    }

    How this i s Possible pls send .

    Mainly wathchin on Process Method

    • Marked as answer by Sudipda Wednesday, January 23, 2013 11:58 AM
    Tuesday, January 22, 2013 7:25 AM