1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-16 08:09:32 +02:00

Implement perceived loudness normalization in new Loudness effect.

This commit is contained in:
Max Maisel 2019-03-21 19:42:52 +01:00
parent 8555018bd4
commit d9608cddea
2 changed files with 24 additions and 22 deletions

View File

@ -147,7 +147,7 @@ bool EffectLoudness::Startup()
// Load the old "current" settings
if (gPrefs->Exists(base))
{
mStereoInd = true;
mStereoInd = false;
mDualMono = DEF_DualMono;
mNormalizeTo = kLoudness;
mLUFSLevel = DEF_LUFSLevel;
@ -160,7 +160,6 @@ bool EffectLoudness::Startup()
return true;
}
// TODO: more method extraction
bool EffectLoudness::Process()
{
if(mNormalizeTo == kLoudness)
@ -205,7 +204,8 @@ bool EffectLoudness::Process()
mProcStereo = range.size() > 1;
InitTrackAnalysis();
mLoudnessProcessor.reset(new EBUR128(mCurRate, range.size()));
mLoudnessProcessor->Initialize();
if(!ProcessOne(range, true))
{
// Processing failed -> abort
@ -214,10 +214,17 @@ bool EffectLoudness::Process()
}
// Calculate normalization values the analysis results
float extent = 1.0;
// TODO: add it in separate method
float extent = mLoudnessProcessor->IntegrativeLoudness();
mMult = mRatio / extent;
// Target half the LUFS value if mono (or independent processed stereo)
// shall be treated as dual mono.
if(range.size() == 1 && (mDualMono || track->GetChannel() != Track::MonoChannel))
mMult /= 2.0;
// LUFS are related to square values so the multiplier must be the root.
mMult = sqrt(mMult);
mProgressMsg = topMsg + wxString::Format(_("Processing: %s"), trackName);
if(!ProcessOne(range, false))
{
@ -228,6 +235,7 @@ bool EffectLoudness::Process()
}
this->ReplaceProcessedTracks(bGoodResult);
mLoudnessProcessor.reset();
FreeBuffers();
return bGoodResult;
}
@ -325,9 +333,7 @@ void EffectLoudness::AllocBuffers()
stereoTrackFound = true;
}
// TODO: hist and block buffers go here
// Initiate a processing buffer. This buffer will (most likely)
// Initiate a processing buffer. This buffer will (most likely)
// be shorter than the length of the track being processed.
mTrackBuffer[0].reinit(mTrackBufferCapacity);
@ -339,13 +345,6 @@ void EffectLoudness::FreeBuffers()
{
mTrackBuffer[0].reset();
mTrackBuffer[1].reset();
// TODO: additional destroy -> function
}
void EffectLoudness::InitTrackAnalysis()
{
mCount = 0;
// TODO: additional init goes here
}
/// ProcessOne() takes a track, transforms it to bunch of buffer-blocks,
@ -399,8 +398,6 @@ bool EffectLoudness::ProcessOne(TrackIterRange<WaveTrack> range, bool analyse)
return false;
}
sleep(1);
if(!analyse)
StoreBufferBlock(range, s, blockLen);
@ -438,8 +435,13 @@ bool EffectLoudness::LoadBufferBlock(TrackIterRange<WaveTrack> range,
/// (for loudness).
bool EffectLoudness::AnalyseBufferBlock()
{
// TODO: analysis loop goes here
mCount += mTrackBufferLen;
for(size_t i = 0; i < mTrackBufferLen; i++)
{
mLoudnessProcessor->ProcessSampleFromChannel(mTrackBuffer[0][i], 0);
if(mProcStereo)
mLoudnessProcessor->ProcessSampleFromChannel(mTrackBuffer[1][i], 1);
mLoudnessProcessor->NextSample();
}
if(!UpdateProgress())
return false;
@ -496,7 +498,7 @@ void EffectLoudness::UpdateUI()
mWarning->SetLabel(wxT(""));
EnableApply(true);
// Changing the prompts causes an unwanted UpdateUI event.
// Changing the prompts causes an unwanted UpdateUI event.
// This 'guard' stops that becoming an infinite recursion.
if (mNormalizeTo != mGUINormalizeTo)
{

View File

@ -20,6 +20,7 @@
#include "Effect.h"
#include "Biquad.h"
#include "EBUR128.h"
class ShuttleGui;
@ -61,7 +62,6 @@ private:
void AllocBuffers();
void FreeBuffers();
void InitTrackAnalysis();
bool ProcessOne(TrackIterRange<WaveTrack> range, bool analyse);
bool LoadBufferBlock(TrackIterRange<WaveTrack> range,
sampleCount pos, size_t len);
@ -92,7 +92,7 @@ private:
float mMult;
float mRatio;
sampleCount mCount;
std::unique_ptr<EBUR128> mLoudnessProcessor;
wxTextCtrl *mLevelTextCtrl;
wxStaticText *mLeveldB;