mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 23:29:41 +02:00
Implement compressor gain calculation and preview.
Signed-off-by: Max Maisel <max.maisel@posteo.de>
This commit is contained in:
parent
ac277c61d7
commit
7326edbefe
@ -18,6 +18,7 @@
|
||||
#include "Compressor2.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <numeric>
|
||||
|
||||
#include <wx/intl.h>
|
||||
#include <wx/valgen.h>
|
||||
@ -270,6 +271,9 @@ void EffectCompressor2::PopulateOrExchange(ShuttleGui & S)
|
||||
plot = mGainPlot->GetPlotData(0);
|
||||
plot->pen = std::unique_ptr<wxPen>(
|
||||
safenew wxPen(AColor::WideEnvelopePen));
|
||||
plot->xdata.resize(61);
|
||||
plot->ydata.resize(61);
|
||||
std::iota(plot->xdata.begin(), plot->xdata.end(), -60);
|
||||
|
||||
mResponsePlot = S.MinSize( { 200, 200 } )
|
||||
.AddPlot({}, 0, 5, -0.2, 1.2, XO("s"), XO(""),
|
||||
@ -465,6 +469,46 @@ 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;
|
||||
double envDB = LINEAR_TO_DB(env);
|
||||
|
||||
// envDB can become NaN is env is exactly zero.
|
||||
// As solution, use a very low dB value to prevent NaN propagation.
|
||||
if(isnan(envDB))
|
||||
envDB = -200;
|
||||
|
||||
kneeCond = 2.0 * (envDB - mThresholdDB);
|
||||
if(kneeCond < -mKneeWidthDB)
|
||||
{
|
||||
// Below threshold: only apply make-up gain
|
||||
return mMakeupGain;
|
||||
}
|
||||
else if(kneeCond >= mKneeWidthDB)
|
||||
{
|
||||
// Above threshold: apply compression and make-up gain
|
||||
return DB_TO_LINEAR(mThresholdDB +
|
||||
(envDB - mThresholdDB) / mRatio + mMakeupGainDB - envDB);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Within knee: apply interpolated compression and make-up gain
|
||||
return DB_TO_LINEAR(
|
||||
(1.0 / mRatio - 1.0)
|
||||
* pow(envDB - mThresholdDB + mKneeWidthDB / 2.0, 2)
|
||||
/ (2.0 * mKneeWidthDB) + mMakeupGainDB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EffectCompressor2::OnUpdateUI(wxCommandEvent & WXUNUSED(evt))
|
||||
{
|
||||
if(!mIgnoreGuiEvents)
|
||||
@ -474,14 +518,30 @@ void EffectCompressor2::OnUpdateUI(wxCommandEvent & WXUNUSED(evt))
|
||||
|
||||
void EffectCompressor2::UpdateUI()
|
||||
{
|
||||
PlotData* plot;
|
||||
plot = mGainPlot->GetPlotData(0);
|
||||
plot->xdata = {-60, -40, 0};
|
||||
plot->ydata = {-60, -40, -20};
|
||||
mGainPlot->Refresh(false);
|
||||
UpdateCompressorPlot();
|
||||
|
||||
// TODO: update plots
|
||||
PlotData* plot;
|
||||
plot = mResponsePlot->GetPlotData(1);
|
||||
plot->xdata = {0, 2, 2, 3, 3, 5};
|
||||
plot->ydata = {0, 0.5, 1, 1, 0.5, 0};
|
||||
mResponsePlot->Refresh(false);
|
||||
}
|
||||
|
||||
void EffectCompressor2::UpdateCompressorPlot()
|
||||
{
|
||||
PlotData* plot;
|
||||
plot = mGainPlot->GetPlotData(0);
|
||||
wxASSERT(plot->xdata.size() == plot->ydata.size());
|
||||
|
||||
InitGainCalculation();
|
||||
size_t xsize = plot->xdata.size();
|
||||
for(size_t i = 0; i < xsize; ++i)
|
||||
plot->ydata[i] = plot->xdata[i] +
|
||||
LINEAR_TO_DB(CompressorGain(DB_TO_LINEAR(plot->xdata[i])));
|
||||
|
||||
// XXX: accessibility but fails with TranslatableString required
|
||||
// mGainPlot->SetName(wxString::Format(
|
||||
// "Compressor gain reduction: %.1f dB", plot->ydata[xsize-1]));
|
||||
mGainPlot->Refresh(false);
|
||||
}
|
||||
|
@ -58,12 +58,14 @@ public:
|
||||
|
||||
private:
|
||||
// EffectCompressor2 implementation
|
||||
void InitGainCalculation();
|
||||
double CompressorGain(double env);
|
||||
|
||||
bool UpdateProgress();
|
||||
void OnUpdateUI(wxCommandEvent & evt);
|
||||
void UpdateUI();
|
||||
void UpdateCompressorPlot();
|
||||
|
||||
private:
|
||||
int mAlgorithm;
|
||||
int mCompressBy;
|
||||
bool mStereoInd;
|
||||
@ -78,6 +80,10 @@ private:
|
||||
double mMakeupGainPct;
|
||||
double mDryWetPct;
|
||||
|
||||
// cached intermediate values
|
||||
double mMakeupGain;
|
||||
double mMakeupGainDB;
|
||||
|
||||
Plot* mGainPlot;
|
||||
Plot* mResponsePlot;
|
||||
bool mIgnoreGuiEvents;
|
||||
|
Loading…
x
Reference in New Issue
Block a user