mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 07:09:43 +02:00
Replace Compressor2 dynamic makeup gain with fixed output gain.
Signed-off-by: Max Maisel <max.maisel@posteo.de>
This commit is contained in:
parent
5c14ec43d3
commit
c534e07424
@ -19,7 +19,7 @@ data.attack_time = raw_data(:,4);
|
||||
data.release_time = raw_data(:,5);
|
||||
data.lookahead_time = raw_data(:,6);
|
||||
data.lookbehind_time = raw_data(:,7);
|
||||
data.makeup_gain_pct = raw_data(:,8);
|
||||
data.output_gain_DB = raw_data(:,8);
|
||||
|
||||
if stereo
|
||||
data.in = horzcat(raw_data(:,9), raw_data(:,10));
|
||||
@ -44,7 +44,7 @@ plot(data.attack_time.*10, 'c', "linewidth", 2);
|
||||
plot(data.release_time.*10, 'c', "linewidth", 2);
|
||||
plot(data.lookahead_time, 'm');
|
||||
plot(data.lookbehind_time, 'm');
|
||||
plot(data.makeup_gain_pct, 'r');
|
||||
plot(data.output_gain_DB, 'r');
|
||||
plot(data.env.*100, 'k', "linewidth", 2);
|
||||
plot(data.gain.*50, 'k', "linestyle", '--');
|
||||
hold off;
|
||||
@ -53,9 +53,9 @@ grid;
|
||||
if stereo
|
||||
legend("in*100", "in*100", "out*100", "out*100", "threshold", "ratio", ...
|
||||
"kneewidth", "attack*10", "release*10", "lookahead", "lookbehind", ...
|
||||
"makeup", "env*100", "gain*50");
|
||||
"out_gain", "env*100", "gain*50");
|
||||
else
|
||||
legend("in*100", "out*100", "threshold", "ratio", ...
|
||||
"kneewidth", "attack*10", "release*10", "lookahead", "lookbehind", ...
|
||||
"makeup", "env*100", "gain*50");
|
||||
"out_gain", "env*100", "gain*50");
|
||||
end
|
||||
|
@ -89,7 +89,7 @@ Param( AttackTime, double, wxT("AttackTime"), 0.2, 0.0001, 30.
|
||||
Param( ReleaseTime, double, wxT("ReleaseTime"), 1.0, 0.0001, 30.0, 2000.0 );
|
||||
Param( LookaheadTime, double, wxT("LookaheadTime"), 0.0, 0.0, 10.0, 200.0 );
|
||||
Param( LookbehindTime, double, wxT("LookbehindTime"), 0.1, 0.0, 10.0, 200.0 );
|
||||
Param( MakeupGain, double, wxT("MakeupGain"), 0.0, 0.0, 100.0, 1.0 );
|
||||
Param( OutputGain, double, wxT("OutputGain"), 0.0, 0.0, 50.0, 10.0 );
|
||||
|
||||
inline int ScaleToPrecision(double scale)
|
||||
{
|
||||
@ -548,7 +548,7 @@ EffectCompressor2::EffectCompressor2()
|
||||
mReleaseTime = DEF_ReleaseTime; // seconds
|
||||
mLookaheadTime = DEF_LookaheadTime;
|
||||
mLookbehindTime = DEF_LookbehindTime;
|
||||
mMakeupGainPct = DEF_MakeupGain;
|
||||
mOutputGainDB = DEF_OutputGain;
|
||||
|
||||
SetLinearEffectFlag(false);
|
||||
}
|
||||
@ -682,7 +682,7 @@ bool EffectCompressor2::DefineParams( ShuttleParams & S )
|
||||
S.SHUTTLE_PARAM(mReleaseTime, ReleaseTime);
|
||||
S.SHUTTLE_PARAM(mLookaheadTime, LookaheadTime);
|
||||
S.SHUTTLE_PARAM(mLookbehindTime, LookbehindTime);
|
||||
S.SHUTTLE_PARAM(mMakeupGainPct, MakeupGain);
|
||||
S.SHUTTLE_PARAM(mOutputGainDB, OutputGain);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -700,7 +700,7 @@ bool EffectCompressor2::GetAutomationParameters(CommandParameters & parms)
|
||||
parms.Write(KEY_ReleaseTime, mReleaseTime);
|
||||
parms.Write(KEY_LookaheadTime, mLookaheadTime);
|
||||
parms.Write(KEY_LookbehindTime, mLookbehindTime);
|
||||
parms.Write(KEY_MakeupGain, mMakeupGainPct);
|
||||
parms.Write(KEY_OutputGain, mOutputGainDB);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -718,7 +718,7 @@ bool EffectCompressor2::SetAutomationParameters(CommandParameters & parms)
|
||||
ReadAndVerifyDouble(ReleaseTime);
|
||||
ReadAndVerifyDouble(LookaheadTime);
|
||||
ReadAndVerifyDouble(LookbehindTime);
|
||||
ReadAndVerifyDouble(MakeupGain);
|
||||
ReadAndVerifyDouble(OutputGain);
|
||||
|
||||
mAlgorithm = Algorithm;
|
||||
mCompressBy = CompressBy;
|
||||
@ -731,7 +731,7 @@ bool EffectCompressor2::SetAutomationParameters(CommandParameters & parms)
|
||||
mReleaseTime = ReleaseTime;
|
||||
mLookaheadTime = LookaheadTime;
|
||||
mLookbehindTime = LookbehindTime;
|
||||
mMakeupGainPct = MakeupGain;
|
||||
mOutputGainDB = OutputGain;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -760,7 +760,7 @@ bool EffectCompressor2::Startup()
|
||||
mReleaseTime = DEF_ReleaseTime; // seconds
|
||||
mLookaheadTime = DEF_LookaheadTime;
|
||||
mLookbehindTime = DEF_LookbehindTime;
|
||||
mMakeupGainPct = DEF_MakeupGain;
|
||||
mOutputGainDB = DEF_OutputGain;
|
||||
|
||||
SaveUserPreset(GetCurrentSettingsGroup());
|
||||
|
||||
@ -805,7 +805,6 @@ bool EffectCompressor2::Process()
|
||||
|
||||
mProcStereo = range.size() > 1;
|
||||
|
||||
InitGainCalculation();
|
||||
mPreproc = InitPreprocessor(mSampleRate);
|
||||
mEnvelope = InitEnvelope(mSampleRate, mPipeline[0].capacity());
|
||||
|
||||
@ -973,16 +972,15 @@ void EffectCompressor2::PopulateOrExchange(ShuttleGui & S)
|
||||
S.AddVariableText(XO("dB"), true,
|
||||
wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
/* i18n-hint: Make-up, i.e. correct for any reduction, rather than fabricate it.*/
|
||||
S.AddVariableText(XO("Make-up Gain:"), true,
|
||||
S.AddVariableText(XO("Output Gain:"), true,
|
||||
wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL);
|
||||
ctrl = S.Name(XO("Make-up Gain"))
|
||||
ctrl = S.Name(XO("Output Gain"))
|
||||
.Style(SliderTextCtrl::HORIZONTAL)
|
||||
.AddSliderTextCtrl({}, DEF_MakeupGain, MAX_MakeupGain,
|
||||
MIN_MakeupGain, ScaleToPrecision(SCL_MakeupGain),
|
||||
&mMakeupGainPct);
|
||||
.AddSliderTextCtrl({}, DEF_OutputGain, MAX_OutputGain,
|
||||
MIN_OutputGain, ScaleToPrecision(SCL_OutputGain),
|
||||
&mOutputGainDB);
|
||||
ctrl->SetMinTextboxWidth(textbox_width);
|
||||
S.AddVariableText(XO("%"), true,
|
||||
S.AddVariableText(XO("dB"), true,
|
||||
wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
}
|
||||
S.EndMultiColumn();
|
||||
@ -1075,13 +1073,6 @@ bool EffectCompressor2::TransferDataFromWindow()
|
||||
|
||||
// EffectCompressor2 implementation
|
||||
|
||||
void EffectCompressor2::InitGainCalculation()
|
||||
{
|
||||
mMakeupGainDB = mMakeupGainPct / 100.0 *
|
||||
-(mThresholdDB * (1.0 - 1.0 / mRatio));
|
||||
mMakeupGain = DB_TO_LINEAR(mMakeupGainDB);
|
||||
}
|
||||
|
||||
double EffectCompressor2::CompressorGain(double env)
|
||||
{
|
||||
double kneeCond;
|
||||
@ -1096,13 +1087,13 @@ double EffectCompressor2::CompressorGain(double env)
|
||||
if(kneeCond < -mKneeWidthDB)
|
||||
{
|
||||
// Below threshold: only apply make-up gain
|
||||
return mMakeupGain;
|
||||
return DB_TO_LINEAR(mOutputGainDB);
|
||||
}
|
||||
else if(kneeCond >= mKneeWidthDB)
|
||||
{
|
||||
// Above threshold: apply compression and make-up gain
|
||||
return DB_TO_LINEAR(mThresholdDB +
|
||||
(envDB - mThresholdDB) / mRatio + mMakeupGainDB - envDB);
|
||||
(envDB - mThresholdDB) / mRatio + mOutputGainDB - envDB);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1110,7 +1101,7 @@ double EffectCompressor2::CompressorGain(double env)
|
||||
return DB_TO_LINEAR(
|
||||
(1.0 / mRatio - 1.0)
|
||||
* pow(envDB - mThresholdDB + mKneeWidthDB / 2.0, 2)
|
||||
/ (2.0 * mKneeWidthDB) + mMakeupGainDB);
|
||||
/ (2.0 * mKneeWidthDB) + mOutputGainDB);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1500,7 +1491,7 @@ inline void EffectCompressor2::CompressSample(float env, size_t wp)
|
||||
float ReleaseTime = mReleaseTime;
|
||||
float LookaheadTime = mLookaheadTime;
|
||||
float LookbehindTime = mLookbehindTime;
|
||||
float MakeupGainPct = mMakeupGainPct;
|
||||
float OutputGainDB = mOutputGainDB;
|
||||
|
||||
debugfile.write((char*)&ThresholdDB, sizeof(float));
|
||||
debugfile.write((char*)&Ratio, sizeof(float));
|
||||
@ -1509,7 +1500,7 @@ inline void EffectCompressor2::CompressSample(float env, size_t wp)
|
||||
debugfile.write((char*)&ReleaseTime, sizeof(float));
|
||||
debugfile.write((char*)&LookaheadTime, sizeof(float));
|
||||
debugfile.write((char*)&LookbehindTime, sizeof(float));
|
||||
debugfile.write((char*)&MakeupGainPct, sizeof(float));
|
||||
debugfile.write((char*)&OutputGainDB, sizeof(float));
|
||||
debugfile.write((char*)&mPipeline[0][0][wp], sizeof(float));
|
||||
if(mProcStereo)
|
||||
debugfile.write((char*)&mPipeline[0][1][wp], sizeof(float));
|
||||
@ -1641,10 +1632,9 @@ void EffectCompressor2::UpdateCompressorPlot()
|
||||
return;
|
||||
if(!IsInRange(mKneeWidthDB, MIN_KneeWidth, MAX_KneeWidth))
|
||||
return;
|
||||
if(!IsInRange(mMakeupGainPct, MIN_MakeupGain, MAX_MakeupGain))
|
||||
if(!IsInRange(mOutputGainDB, MIN_OutputGain, MAX_OutputGain))
|
||||
return;
|
||||
|
||||
InitGainCalculation();
|
||||
size_t xsize = plot->xdata.size();
|
||||
for(size_t i = 0; i < xsize; ++i)
|
||||
plot->ydata[i] = plot->xdata[i] +
|
||||
@ -1678,7 +1668,6 @@ void EffectCompressor2::UpdateResponsePlot()
|
||||
lookahead_size -= (lookahead_size > 0);
|
||||
ssize_t block_size = float(TAU_FACTOR) * (mAttackTime + 1.0) * plot_rate;
|
||||
|
||||
InitGainCalculation();
|
||||
preproc = InitPreprocessor(plot_rate, true);
|
||||
envelope = InitEnvelope(plot_rate, block_size, true);
|
||||
|
||||
|
@ -209,7 +209,6 @@ public:
|
||||
|
||||
private:
|
||||
// EffectCompressor2 implementation
|
||||
void InitGainCalculation();
|
||||
double CompressorGain(double env);
|
||||
std::unique_ptr<SamplePreprocessor> InitPreprocessor(
|
||||
double rate, bool preview = false);
|
||||
@ -269,11 +268,9 @@ private:
|
||||
double mReleaseTime;
|
||||
double mLookaheadTime;
|
||||
double mLookbehindTime;
|
||||
double mMakeupGainPct;
|
||||
double mOutputGainDB;
|
||||
|
||||
// cached intermediate values
|
||||
double mMakeupGain;
|
||||
double mMakeupGainDB;
|
||||
size_t mLookaheadLength;
|
||||
|
||||
static const size_t RESPONSE_PLOT_SAMPLES = 200;
|
||||
|
@ -48,8 +48,7 @@ function y = env_PT1_asym(x, fs, t_a, t_r, gain = 0)
|
||||
end
|
||||
|
||||
## Compressor gain helper function
|
||||
function gain = comp_gain(env, thresh_DB, ratio, kneeW_DB, makeup)
|
||||
makeupG_DB = -thresh_DB * (1-1/ratio) * makeup / 100;
|
||||
function gain = comp_gain(env, thresh_DB, ratio, kneeW_DB, outG_DB)
|
||||
env_DB = 20*log10(env);
|
||||
kneeCond_DB = 2*(env_DB-thresh_DB);
|
||||
|
||||
@ -59,15 +58,15 @@ function gain = comp_gain(env, thresh_DB, ratio, kneeW_DB, makeup)
|
||||
withinKnee = (kneeCond_DB >= -kneeW_DB) & (kneeCond_DB < kneeW_DB);
|
||||
|
||||
gain_DB = zeros(size(env));
|
||||
gain_DB(belowKnee) = makeupG_DB;
|
||||
gain_DB(belowKnee) = outG_DB;
|
||||
gain_DB(aboveKnee) = thresh_DB + ...
|
||||
(env_DB(aboveKnee) - thresh_DB) / ratio + ...
|
||||
makeupG_DB - env_DB(aboveKnee);
|
||||
outG_DB - env_DB(aboveKnee);
|
||||
# Prevent division by zero
|
||||
kneeW_DB(kneeW_DB==0) = 0.000001;
|
||||
gain_DB(withinKnee) = (1/ratio-1) * ...
|
||||
(env_DB(withinKnee) - thresh_DB + kneeW_DB/2).^2 / ...
|
||||
(2*kneeW_DB) + makeupG_DB;
|
||||
(2*kneeW_DB) + outG_DB;
|
||||
|
||||
gain = 10.^(gain_DB/20);
|
||||
end
|
||||
@ -173,7 +172,7 @@ CURRENT_TEST = "Compressor2, mono compression PT1 - sinewave - asymetric attack
|
||||
x2 = sin(2*pi*300/fs*(1:1:20*fs)).';
|
||||
remove_all_tracks();
|
||||
x = export_to_aud(x2, fs, "Compressor-mono-sine-test.wav");
|
||||
aud_do("DynamicCompressor: Threshold=-6 Algorithm=1 CompressBy=0 Ratio=2.0 AttackTime=1.0 ReleaseTime=0.3 LookaheadTime=0 LookbehindTime=0 KneeWidth=0 MakeupGain=0\n");
|
||||
aud_do("DynamicCompressor: Threshold=-6 Algorithm=1 CompressBy=0 Ratio=2.0 AttackTime=1.0 ReleaseTime=0.3 LookaheadTime=0 LookbehindTime=0 KneeWidth=0 OutputGain=0\n");
|
||||
y = import_from_aud(1);
|
||||
|
||||
do_test_equ(settled(y, fs, 1), ...
|
||||
@ -184,22 +183,22 @@ do_test_equ(settled(y, fs, 1), ...
|
||||
CURRENT_TEST = "Compressor2, mono asymmetric lookaround max";
|
||||
remove_all_tracks();
|
||||
x = export_to_aud(x1, fs);
|
||||
aud_do("DynamicCompressor: Threshold=-17 Algorithm=1 CompressBy=0 Ratio=1.2 AttackTime=0.3 ReleaseTime=0.3 LookaheadTime=0.2 LookbehindTime=0.1 KneeWidth=5 MakeupGain=50\n");
|
||||
aud_do("DynamicCompressor: Threshold=-17 Algorithm=1 CompressBy=0 Ratio=1.2 AttackTime=0.3 ReleaseTime=0.3 LookaheadTime=0.2 LookbehindTime=0.1 KneeWidth=5 OutputGain=1\n");
|
||||
y = import_from_aud(1);
|
||||
|
||||
do_test_equ(settled(y, fs, 0.6), ...
|
||||
comp_gain(settled(env_PT1(lookaround_max(x, fs, 0.2, 0.1), fs, 0.3, 1), fs, 0.6), ...
|
||||
-17, 1.2, 5, 50).*settled(x, fs, 0.6));
|
||||
-17, 1.2, 5, 1).*settled(x, fs, 0.6));
|
||||
|
||||
## Test Compressor, mono lookaround RMS
|
||||
CURRENT_TEST = "Compressor2, mono asymmetric lookaround RMS";
|
||||
remove_all_tracks();
|
||||
x = export_to_aud(x1, fs);
|
||||
aud_do("DynamicCompressor: Threshold=-20 Algorithm=1 CompressBy=1 Ratio=3 AttackTime=1 ReleaseTime=1 LookaheadTime=0.1 LookbehindTime=0.2 KneeWidth=3 MakeupGain=80\n");
|
||||
aud_do("DynamicCompressor: Threshold=-20 Algorithm=1 CompressBy=1 Ratio=3 AttackTime=1 ReleaseTime=1 LookaheadTime=0.1 LookbehindTime=0.2 KneeWidth=3 OutputGain=2\n");
|
||||
y = import_from_aud(1);
|
||||
|
||||
do_test_equ(settled(y, fs, 2), ...
|
||||
comp_gain(settled(env_PT1(lookaround_RMS(x, fs, 0.1, 0.2), fs, 1), fs, 2), -20, 3, 3, 80) ...
|
||||
comp_gain(settled(env_PT1(lookaround_RMS(x, fs, 0.1, 0.2), fs, 1), fs, 2), -20, 3, 3, 2) ...
|
||||
.*settled(x, fs, 2));
|
||||
|
||||
## Test Compressor, mono lookaround max with selection
|
||||
@ -208,13 +207,13 @@ remove_all_tracks();
|
||||
x = export_to_aud(x1, fs);
|
||||
|
||||
aud_do("Select: Start=2 End=5 Mode=Set\n");
|
||||
aud_do("DynamicCompressor: Threshold=-17 Algorithm=1 CompressBy=0 Ratio=1.2 AttackTime=0.3 ReleaseTime=0.3 LookaheadTime=0.2 LookbehindTime=0.2 KneeWidth=5 MakeupGain=50\n");
|
||||
aud_do("DynamicCompressor: Threshold=-17 Algorithm=1 CompressBy=0 Ratio=1.2 AttackTime=0.3 ReleaseTime=0.3 LookaheadTime=0.2 LookbehindTime=0.2 KneeWidth=5 OutputGain=0.5\n");
|
||||
y = import_from_aud(1);
|
||||
x = x(2*fs+1:5*fs);
|
||||
|
||||
do_test_equ(settled(y, fs, 0.1), ...
|
||||
comp_gain(settled(env_PT1(lookaround_max(x, fs, 0.2, 0.2), fs, 0.3, 1), fs, 0.1), ...
|
||||
-17, 1.2, 5, 50).*settled(x, fs, 0.1));
|
||||
-17, 1.2, 5, 0.5).*settled(x, fs, 0.1));
|
||||
|
||||
## Test Compressor, mono, ultra short attack time
|
||||
CURRENT_TEST = "Compressor2, mono, ultra short attack time";
|
||||
@ -287,20 +286,20 @@ do_test_equ(settled(y(:,2), fs, 1), ...
|
||||
CURRENT_TEST = "Compressor2, stereo lookaround max";
|
||||
remove_all_tracks();
|
||||
x = export_to_aud(x1, fs);
|
||||
aud_do("DynamicCompressor: Threshold=-17 Algorithm=1 Ratio=1.2 AttackTime=0.3 ReleaseTime=0.3 LookaheadTime=0.2 LookbehindTime=0.2 KneeWidth=5 MakeupGain=50\n");
|
||||
aud_do("DynamicCompressor: Threshold=-17 Algorithm=1 Ratio=1.2 AttackTime=0.3 ReleaseTime=0.3 LookaheadTime=0.2 LookbehindTime=0.2 KneeWidth=5 OutputGain=1\n");
|
||||
y = import_from_aud(2);
|
||||
|
||||
do_test_equ(settled(y, fs, 0.6), ...
|
||||
comp_gain(settled(env_PT1(lookaround_max(x, fs, 0.2, 0.2), fs, 0.3, 1), fs, 0.6), ...
|
||||
-17, 1.2, 5, 50).*settled(x, fs, 0.6));
|
||||
-17, 1.2, 5, 1).*settled(x, fs, 0.6));
|
||||
|
||||
## Test Compressor, stereo lookaround RMS
|
||||
CURRENT_TEST = "Compressor2, stereo lookaround RMS";
|
||||
remove_all_tracks();
|
||||
x = export_to_aud(x1, fs);
|
||||
aud_do("DynamicCompressor: Threshold=-20 Algorithm=1 Ratio=3 AttackTime=1 ReleaseTime=1 LookaheadTime=0.1 LookbehindTime=0.1 KneeWidth=3 CompressBy=1 MakeupGain=60\n");
|
||||
aud_do("DynamicCompressor: Threshold=-20 Algorithm=1 Ratio=3 AttackTime=1 ReleaseTime=1 LookaheadTime=0.1 LookbehindTime=0.1 KneeWidth=3 CompressBy=1 OutputGain=1.3\n");
|
||||
y = import_from_aud(2);
|
||||
|
||||
do_test_equ(settled(y, fs, 2.5), ...
|
||||
comp_gain(settled(env_PT1(lookaround_RMS(x, fs, 0.1, 0.1), fs, 1), fs, 2.5), -20, 3, 3, 60) ...
|
||||
comp_gain(settled(env_PT1(lookaround_RMS(x, fs, 0.1, 0.1), fs, 1), fs, 2.5), -20, 3, 3, 1.3) ...
|
||||
.*settled(x, fs, 2.5));
|
||||
|
Loading…
x
Reference in New Issue
Block a user