mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 23:29:41 +02:00
Draw full compressor response plot
instead of just the envelope detector step response. Also increase minimum plot width for non realtime enabled case. Signed-off-by: Max Maisel <max.maisel@posteo.de>
This commit is contained in:
parent
90d7c1d226
commit
3d4e504bc3
@ -131,9 +131,9 @@ float SlidingRmsPreprocessor::ProcessSample(float valueL, float valueR)
|
|||||||
return DoProcessSample((valueL * valueL + valueR * valueR) / 2.0);
|
return DoProcessSample((valueL * valueL + valueR * valueR) / 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlidingRmsPreprocessor::Reset()
|
void SlidingRmsPreprocessor::Reset(float level)
|
||||||
{
|
{
|
||||||
mSum = 0;
|
mSum = (level / mGain) * (level / mGain) * float(mWindow.size());
|
||||||
mPos = 0;
|
mPos = 0;
|
||||||
mInsertCount = 0;
|
mInsertCount = 0;
|
||||||
std::fill(mWindow.begin(), mWindow.end(), 0);
|
std::fill(mWindow.begin(), mWindow.end(), 0);
|
||||||
@ -203,11 +203,11 @@ float SlidingMaxPreprocessor::ProcessSample(float valueL, float valueR)
|
|||||||
return DoProcessSample((fabs(valueL) + fabs(valueR)) / 2.0);
|
return DoProcessSample((fabs(valueL) + fabs(valueR)) / 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlidingMaxPreprocessor::Reset()
|
void SlidingMaxPreprocessor::Reset(float value)
|
||||||
{
|
{
|
||||||
mPos = 0;
|
mPos = 0;
|
||||||
std::fill(mWindow.begin(), mWindow.end(), 0);
|
std::fill(mWindow.begin(), mWindow.end(), value);
|
||||||
std::fill(mMaxes.begin(), mMaxes.end(), 0);
|
std::fill(mMaxes.begin(), mMaxes.end(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SlidingMaxPreprocessor::SetWindowSize(size_t windowSize)
|
void SlidingMaxPreprocessor::SetWindowSize(size_t windowSize)
|
||||||
@ -303,6 +303,13 @@ ExpFitEnvelopeDetector::ExpFitEnvelopeDetector(
|
|||||||
SetParams(rate, attackTime, releaseTime);
|
SetParams(rate, attackTime, releaseTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExpFitEnvelopeDetector::Reset(float value)
|
||||||
|
{
|
||||||
|
std::fill(mProcessedBuffer.begin(), mProcessedBuffer.end(), value);
|
||||||
|
std::fill(mProcessingBuffer.begin(), mProcessingBuffer.end(), value);
|
||||||
|
std::fill(mLookaheadBuffer.begin(), mLookaheadBuffer.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
void ExpFitEnvelopeDetector::SetParams(
|
void ExpFitEnvelopeDetector::SetParams(
|
||||||
float sampleRate, float attackTime, float releaseTime)
|
float sampleRate, float attackTime, float releaseTime)
|
||||||
{
|
{
|
||||||
@ -410,6 +417,14 @@ float Pt1EnvelopeDetector::DecayFactor()
|
|||||||
return mReleaseFactor;
|
return mReleaseFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Pt1EnvelopeDetector::Reset(float value)
|
||||||
|
{
|
||||||
|
value *= mGainCorrection;
|
||||||
|
std::fill(mProcessedBuffer.begin(), mProcessedBuffer.end(), value);
|
||||||
|
std::fill(mProcessingBuffer.begin(), mProcessingBuffer.end(), value);
|
||||||
|
std::fill(mLookaheadBuffer.begin(), mLookaheadBuffer.end(), value);
|
||||||
|
}
|
||||||
|
|
||||||
void Pt1EnvelopeDetector::SetParams(
|
void Pt1EnvelopeDetector::SetParams(
|
||||||
float sampleRate, float attackTime, float releaseTime)
|
float sampleRate, float attackTime, float releaseTime)
|
||||||
{
|
{
|
||||||
@ -818,7 +833,7 @@ void EffectCompressor2::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.StartVerticalLay();
|
S.StartVerticalLay();
|
||||||
S.AddVariableText(XO("Envelope dependent gain"), 0,
|
S.AddVariableText(XO("Envelope dependent gain"), 0,
|
||||||
wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
|
wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
|
||||||
mGainPlot = S.MinSize( { 200, 200 } )
|
mGainPlot = S.MinSize( { 400, 200 } )
|
||||||
.AddPlot({}, -60, 0, -60, 0, XO("dB"), XO("dB"),
|
.AddPlot({}, -60, 0, -60, 0, XO("dB"), XO("dB"),
|
||||||
Ruler::LinearDBFormat, Ruler::LinearDBFormat);
|
Ruler::LinearDBFormat, Ruler::LinearDBFormat);
|
||||||
|
|
||||||
@ -832,19 +847,19 @@ void EffectCompressor2::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.EndVerticalLay();
|
S.EndVerticalLay();
|
||||||
S.StartVerticalLay();
|
S.StartVerticalLay();
|
||||||
|
|
||||||
S.AddVariableText(XO("Envelope detector step response"), 0,
|
S.AddVariableText(XO("Compressor step response"), 0,
|
||||||
wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
|
wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
|
||||||
mResponsePlot = S.MinSize( { 200, 200 } )
|
mResponsePlot = S.MinSize( { 400, 200 } )
|
||||||
.AddPlot({}, 0, 5, -0.2, 1.2, XO("s"), XO(""),
|
.AddPlot({}, 0, 5, -0.2, 1.2, XO("s"), XO(""),
|
||||||
Ruler::IntFormat, Ruler::RealFormat, 2);
|
Ruler::IntFormat, Ruler::RealFormat, 2);
|
||||||
mResponsePlot->SetName(XO("Envelope detector step response plot"));
|
mResponsePlot->SetName(XO("Compressor step response plot"));
|
||||||
|
|
||||||
plot = mResponsePlot->GetPlotData(0);
|
plot = mResponsePlot->GetPlotData(0);
|
||||||
plot->pen = std::unique_ptr<wxPen>(
|
plot->pen = std::unique_ptr<wxPen>(
|
||||||
safenew wxPen(AColor::WideEnvelopePen));
|
safenew wxPen(AColor::WideEnvelopePen));
|
||||||
plot->xdata = {0, RESPONSE_PLOT_STEP_START, RESPONSE_PLOT_STEP_START,
|
plot->xdata = {0, RESPONSE_PLOT_STEP_START, RESPONSE_PLOT_STEP_START,
|
||||||
RESPONSE_PLOT_STEP_STOP, RESPONSE_PLOT_STEP_STOP, 5};
|
RESPONSE_PLOT_STEP_STOP, RESPONSE_PLOT_STEP_STOP, 5};
|
||||||
plot->ydata = {0, 0, 1, 1, 0, 0};
|
plot->ydata = {0.1, 0.1, 1, 1, 0.1, 0.1};
|
||||||
|
|
||||||
plot = mResponsePlot->GetPlotData(1);
|
plot = mResponsePlot->GetPlotData(1);
|
||||||
plot->pen = std::unique_ptr<wxPen>(
|
plot->pen = std::unique_ptr<wxPen>(
|
||||||
@ -1655,11 +1670,16 @@ void EffectCompressor2::UpdateResponsePlot()
|
|||||||
float plot_rate = RESPONSE_PLOT_SAMPLES / RESPONSE_PLOT_TIME;
|
float plot_rate = RESPONSE_PLOT_SAMPLES / RESPONSE_PLOT_TIME;
|
||||||
|
|
||||||
size_t lookahead_size = CalcLookaheadLength(plot_rate);
|
size_t lookahead_size = CalcLookaheadLength(plot_rate);
|
||||||
|
lookahead_size -= (lookahead_size > 0);
|
||||||
ssize_t block_size = float(TAU_FACTOR) * (mAttackTime + 1.0) * plot_rate;
|
ssize_t block_size = float(TAU_FACTOR) * (mAttackTime + 1.0) * plot_rate;
|
||||||
|
|
||||||
|
InitGainCalculation();
|
||||||
preproc = InitPreprocessor(plot_rate, true);
|
preproc = InitPreprocessor(plot_rate, true);
|
||||||
envelope = InitEnvelope(plot_rate, block_size, true);
|
envelope = InitEnvelope(plot_rate, block_size, true);
|
||||||
|
|
||||||
|
preproc->Reset(0.1);
|
||||||
|
envelope->Reset(0.1);
|
||||||
|
|
||||||
ssize_t step_start = RESPONSE_PLOT_STEP_START * plot_rate - lookahead_size;
|
ssize_t step_start = RESPONSE_PLOT_STEP_START * plot_rate - lookahead_size;
|
||||||
ssize_t step_stop = RESPONSE_PLOT_STEP_STOP * plot_rate - lookahead_size;
|
ssize_t step_stop = RESPONSE_PLOT_STEP_STOP * plot_rate - lookahead_size;
|
||||||
|
|
||||||
@ -1667,12 +1687,21 @@ void EffectCompressor2::UpdateResponsePlot()
|
|||||||
for(ssize_t i = -lookahead_size; i < 2*block_size; ++i)
|
for(ssize_t i = -lookahead_size; i < 2*block_size; ++i)
|
||||||
{
|
{
|
||||||
if(i < step_start || i > step_stop)
|
if(i < step_start || i > step_stop)
|
||||||
envelope->ProcessSample(preproc->ProcessSample(0));
|
envelope->ProcessSample(preproc->ProcessSample(0.1));
|
||||||
else
|
else
|
||||||
envelope->ProcessSample(preproc->ProcessSample(1));
|
envelope->ProcessSample(preproc->ProcessSample(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(ssize_t i = 0; i < xsize; ++i)
|
for(ssize_t i = 0; i < xsize; ++i)
|
||||||
plot->ydata[i] = envelope->ProcessSample(preproc->ProcessSample(0));
|
{
|
||||||
|
float x = 1;
|
||||||
|
if(i < RESPONSE_PLOT_STEP_START * plot_rate ||
|
||||||
|
i > RESPONSE_PLOT_STEP_STOP * plot_rate)
|
||||||
|
x = 0.1;
|
||||||
|
|
||||||
|
plot->ydata[i] = x * CompressorGain(
|
||||||
|
envelope->ProcessSample(preproc->ProcessSample(0.1)));
|
||||||
|
}
|
||||||
|
|
||||||
mResponsePlot->Refresh(false);
|
mResponsePlot->Refresh(false);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ class SamplePreprocessor
|
|||||||
public:
|
public:
|
||||||
virtual float ProcessSample(float value) = 0;
|
virtual float ProcessSample(float value) = 0;
|
||||||
virtual float ProcessSample(float valueL, float valueR) = 0;
|
virtual float ProcessSample(float valueL, float valueR) = 0;
|
||||||
virtual void Reset() = 0;
|
virtual void Reset(float value = 0) = 0;
|
||||||
virtual void SetWindowSize(size_t windowSize) = 0;
|
virtual void SetWindowSize(size_t windowSize) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ class SlidingRmsPreprocessor : public SamplePreprocessor
|
|||||||
|
|
||||||
virtual float ProcessSample(float value);
|
virtual float ProcessSample(float value);
|
||||||
virtual float ProcessSample(float valueL, float valueR);
|
virtual float ProcessSample(float valueL, float valueR);
|
||||||
virtual void Reset();
|
virtual void Reset(float value = 0);
|
||||||
virtual void SetWindowSize(size_t windowSize);
|
virtual void SetWindowSize(size_t windowSize);
|
||||||
|
|
||||||
static const size_t REFRESH_WINDOW_EVERY = 1048576; // 1 MB
|
static const size_t REFRESH_WINDOW_EVERY = 1048576; // 1 MB
|
||||||
@ -63,7 +63,7 @@ class SlidingMaxPreprocessor : public SamplePreprocessor
|
|||||||
|
|
||||||
virtual float ProcessSample(float value);
|
virtual float ProcessSample(float value);
|
||||||
virtual float ProcessSample(float valueL, float valueR);
|
virtual float ProcessSample(float valueL, float valueR);
|
||||||
virtual void Reset();
|
virtual void Reset(float value = 0);
|
||||||
virtual void SetWindowSize(size_t windowSize);
|
virtual void SetWindowSize(size_t windowSize);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -87,6 +87,7 @@ class EnvelopeDetector
|
|||||||
inline float InitialCondition() const { return mInitialCondition; }
|
inline float InitialCondition() const { return mInitialCondition; }
|
||||||
inline size_t InitialConditionSize() const { return mInitialBlockSize; }
|
inline size_t InitialConditionSize() const { return mInitialBlockSize; }
|
||||||
|
|
||||||
|
virtual void Reset(float value = 0) = 0;
|
||||||
virtual void SetParams(float sampleRate, float attackTime,
|
virtual void SetParams(float sampleRate, float attackTime,
|
||||||
float releaseTime) = 0;
|
float releaseTime) = 0;
|
||||||
|
|
||||||
@ -110,6 +111,7 @@ class ExpFitEnvelopeDetector : public EnvelopeDetector
|
|||||||
ExpFitEnvelopeDetector(float rate, float attackTime, float releaseTime,
|
ExpFitEnvelopeDetector(float rate, float attackTime, float releaseTime,
|
||||||
size_t buffer_size);
|
size_t buffer_size);
|
||||||
|
|
||||||
|
virtual void Reset(float value);
|
||||||
virtual void SetParams(float sampleRate, float attackTime,
|
virtual void SetParams(float sampleRate, float attackTime,
|
||||||
float releaseTime);
|
float releaseTime);
|
||||||
|
|
||||||
@ -127,6 +129,7 @@ class Pt1EnvelopeDetector : public EnvelopeDetector
|
|||||||
size_t buffer_size, bool correctGain = true);
|
size_t buffer_size, bool correctGain = true);
|
||||||
virtual void CalcInitialCondition(float value);
|
virtual void CalcInitialCondition(float value);
|
||||||
|
|
||||||
|
virtual void Reset(float value);
|
||||||
virtual void SetParams(float sampleRate, float attackTime,
|
virtual void SetParams(float sampleRate, float attackTime,
|
||||||
float releaseTime);
|
float releaseTime);
|
||||||
virtual float AttackFactor();
|
virtual float AttackFactor();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user