| 77 | } |
| 78 | |
| 79 | void Compressor::ProcessAudio(double time, ChannelBuffer* buffer) |
| 80 | { |
| 81 | PROFILER(Compressor); |
| 82 | |
| 83 | if (!mEnabled) |
| 84 | return; |
| 85 | |
| 86 | int bufferSize = buffer->BufferSize(); |
| 87 | mDelayBuffer.SetNumChannels(buffer->NumActiveChannels()); |
| 88 | |
| 89 | for (int i = 0; i < bufferSize; ++i) |
| 90 | { |
| 91 | ComputeSliders(i); |
| 92 | |
| 93 | // create sidechain |
| 94 | |
| 95 | float input = 0; |
| 96 | for (int ch = 0; ch < buffer->NumActiveChannels(); ++ch) |
| 97 | input = MAX(input, fabsf(buffer->GetChannel(ch)[i])); |
| 98 | input *= mDrive; |
| 99 | |
| 100 | /* if desired, one could use another EnvelopeDetector to smooth |
| 101 | * the rectified signal. |
| 102 | */ |
| 103 | |
| 104 | // convert key to dB |
| 105 | input += DC_OFFSET; // add DC offset to avoid log( 0 ) |
| 106 | mCurrentInputDb = lin2dB(input); // convert linear -> dB |
| 107 | |
| 108 | // threshold |
| 109 | double overdB = mCurrentInputDb - mThreshold; // delta over threshold |
| 110 | if (overdB < 0.0) |
| 111 | overdB = 0.0; |
| 112 | |
| 113 | // attack/release |
| 114 | |
| 115 | overdB += DC_OFFSET; // add DC offset to avoid denormal |
| 116 | mEnv.run(overdB, envdB_); // run attack/release envelope |
| 117 | overdB = envdB_ - DC_OFFSET; // subtract DC offset |
| 118 | |
| 119 | /* REGARDING THE DC OFFSET: In this case, since the offset is added before |
| 120 | * the attack/release processes, the envelope will never fall below the offset, |
| 121 | * thereby avoiding denormals. However, to prevent the offset from causing |
| 122 | * constant gain reduction, we must subtract it from the envelope, yielding |
| 123 | * a minimum value of 0dB. |
| 124 | */ |
| 125 | |
| 126 | double invRatio = 1 / mRatio; |
| 127 | |
| 128 | // transfer function |
| 129 | double reduction = overdB * (invRatio - 1.0); // gain reduction (dB) |
| 130 | double makeup = (-mThreshold * .5) * (1.0 - invRatio); |
| 131 | mOutputGain = ofLerp(1, dB2lin(reduction + makeup) * mDrive * mOutputAdjust, mMix); |
| 132 | |
| 133 | // output gain |
| 134 | for (int ch = 0; ch < buffer->NumActiveChannels(); ++ch) |
| 135 | { |
| 136 | mDelayBuffer.Write(buffer->GetChannel(ch)[i], ch); |
nothing calls this directly
no test coverage detected