mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-16 16:10:06 +02:00
Remove all Loudness related code from Normalize effect.
This commit is contained in:
parent
e439e8f4c7
commit
c3d25cfb44
@ -253,9 +253,6 @@
|
|||||||
// PRL 31 July 2018
|
// PRL 31 July 2018
|
||||||
#define EXPERIMENTAL_DRAGGABLE_PLAY_HEAD
|
#define EXPERIMENTAL_DRAGGABLE_PLAY_HEAD
|
||||||
|
|
||||||
// mmm-1 22 Aug 2018
|
|
||||||
//#define EXPERIMENTAL_R128_NORM
|
|
||||||
|
|
||||||
// JKC 29 July 2019
|
// JKC 29 July 2019
|
||||||
// OD_DATA made experimental. It is on the way out because
|
// OD_DATA made experimental. It is on the way out because
|
||||||
// it is dangerous and has too many bugs. See bug 536 for example.
|
// it is dangerous and has too many bugs. See bug 536 for example.
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
Dominic Mazzoni
|
Dominic Mazzoni
|
||||||
Vaughan Johnson (Preview)
|
Vaughan Johnson (Preview)
|
||||||
Max Maisel (Loudness)
|
|
||||||
|
|
||||||
*******************************************************************//**
|
*******************************************************************//**
|
||||||
|
|
||||||
@ -43,10 +42,6 @@ Param( PeakLevel, double, wxT("PeakLevel"), -1.0, -145.0, 0.0,
|
|||||||
Param( RemoveDC, bool, wxT("RemoveDcOffset"), true, false, true, 1 );
|
Param( RemoveDC, bool, wxT("RemoveDcOffset"), true, false, true, 1 );
|
||||||
Param( ApplyGain, bool, wxT("ApplyGain"), true, false, true, 1 );
|
Param( ApplyGain, bool, wxT("ApplyGain"), true, false, true, 1 );
|
||||||
Param( StereoInd, bool, wxT("StereoIndependent"), false, false, true, 1 );
|
Param( StereoInd, bool, wxT("StereoIndependent"), false, false, true, 1 );
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
Param( LUFSLevel, double, wxT("LUFSLevel"), -23.0, -145.0, 0.0, 1 );
|
|
||||||
Param( UseLoudness, bool, wxT("UseLoudness"), false, false, true, 1 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(EffectNormalize, wxEvtHandler)
|
BEGIN_EVENT_TABLE(EffectNormalize, wxEvtHandler)
|
||||||
EVT_CHECKBOX(wxID_ANY, EffectNormalize::OnUpdateUI)
|
EVT_CHECKBOX(wxID_ANY, EffectNormalize::OnUpdateUI)
|
||||||
@ -59,10 +54,6 @@ EffectNormalize::EffectNormalize()
|
|||||||
mDC = DEF_RemoveDC;
|
mDC = DEF_RemoveDC;
|
||||||
mGain = DEF_ApplyGain;
|
mGain = DEF_ApplyGain;
|
||||||
mStereoInd = DEF_StereoInd;
|
mStereoInd = DEF_StereoInd;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
mLUFSLevel = DEF_LUFSLevel;
|
|
||||||
mUseLoudness = DEF_UseLoudness;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SetLinearEffectFlag(false);
|
SetLinearEffectFlag(false);
|
||||||
}
|
}
|
||||||
@ -80,11 +71,7 @@ ComponentInterfaceSymbol EffectNormalize::GetSymbol()
|
|||||||
|
|
||||||
wxString EffectNormalize::GetDescription()
|
wxString EffectNormalize::GetDescription()
|
||||||
{
|
{
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
return _("Sets the peak amplitude or loudness of one or more tracks");
|
|
||||||
#else
|
|
||||||
return _("Sets the peak amplitude of one or more tracks");
|
return _("Sets the peak amplitude of one or more tracks");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString EffectNormalize::ManualPage()
|
wxString EffectNormalize::ManualPage()
|
||||||
@ -105,10 +92,6 @@ bool EffectNormalize::DefineParams( ShuttleParams & S ){
|
|||||||
S.SHUTTLE_PARAM( mGain, ApplyGain );
|
S.SHUTTLE_PARAM( mGain, ApplyGain );
|
||||||
S.SHUTTLE_PARAM( mDC, RemoveDC );
|
S.SHUTTLE_PARAM( mDC, RemoveDC );
|
||||||
S.SHUTTLE_PARAM( mStereoInd, StereoInd );
|
S.SHUTTLE_PARAM( mStereoInd, StereoInd );
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
S.SHUTTLE_PARAM( mLUFSLevel, LUFSLevel );
|
|
||||||
S.SHUTTLE_PARAM( mUseLoudness, UseLoudness );
|
|
||||||
#endif
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,10 +101,6 @@ bool EffectNormalize::GetAutomationParameters(CommandParameters & parms)
|
|||||||
parms.Write(KEY_ApplyGain, mGain);
|
parms.Write(KEY_ApplyGain, mGain);
|
||||||
parms.Write(KEY_RemoveDC, mDC);
|
parms.Write(KEY_RemoveDC, mDC);
|
||||||
parms.Write(KEY_StereoInd, mStereoInd);
|
parms.Write(KEY_StereoInd, mStereoInd);
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
parms.Write(KEY_LUFSLevel, mLUFSLevel);
|
|
||||||
parms.Write(KEY_UseLoudness, mUseLoudness);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -132,19 +111,11 @@ bool EffectNormalize::SetAutomationParameters(CommandParameters & parms)
|
|||||||
ReadAndVerifyBool(ApplyGain);
|
ReadAndVerifyBool(ApplyGain);
|
||||||
ReadAndVerifyBool(RemoveDC);
|
ReadAndVerifyBool(RemoveDC);
|
||||||
ReadAndVerifyBool(StereoInd);
|
ReadAndVerifyBool(StereoInd);
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
ReadAndVerifyDouble(LUFSLevel);
|
|
||||||
ReadAndVerifyBool(UseLoudness);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mPeakLevel = PeakLevel;
|
mPeakLevel = PeakLevel;
|
||||||
mGain = ApplyGain;
|
mGain = ApplyGain;
|
||||||
mDC = RemoveDC;
|
mDC = RemoveDC;
|
||||||
mStereoInd = StereoInd;
|
mStereoInd = StereoInd;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
mLUFSLevel = LUFSLevel;
|
|
||||||
mUseLoudness = UseLoudness;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -180,10 +151,6 @@ bool EffectNormalize::Startup()
|
|||||||
mPeakLevel = -mPeakLevel;
|
mPeakLevel = -mPeakLevel;
|
||||||
boolProxy = gPrefs->Read(base + wxT("StereoIndependent"), 0L);
|
boolProxy = gPrefs->Read(base + wxT("StereoIndependent"), 0L);
|
||||||
mStereoInd = (boolProxy == 1);
|
mStereoInd = (boolProxy == 1);
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
mUseLoudness = false;
|
|
||||||
mLUFSLevel = DEF_LUFSLevel;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SaveUserPreset(GetCurrentSettingsGroup());
|
SaveUserPreset(GetCurrentSettingsGroup());
|
||||||
|
|
||||||
@ -203,20 +170,8 @@ bool EffectNormalize::Process()
|
|||||||
float ratio;
|
float ratio;
|
||||||
if( mGain )
|
if( mGain )
|
||||||
{
|
{
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
if(mUseLoudness) {
|
|
||||||
// LU use 10*log10(...) instead of 20*log10(...)
|
|
||||||
// so multiply level by 2 and use standard DB_TO_LINEAR macro.
|
|
||||||
ratio = DB_TO_LINEAR(TrapDouble(mLUFSLevel*2, MIN_LUFSLevel, MAX_LUFSLevel));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// same value used for all tracks
|
|
||||||
ratio = DB_TO_LINEAR(TrapDouble(mPeakLevel, MIN_PeakLevel, MAX_PeakLevel));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// same value used for all tracks
|
// same value used for all tracks
|
||||||
ratio = DB_TO_LINEAR(TrapDouble(mPeakLevel, MIN_PeakLevel, MAX_PeakLevel));
|
ratio = DB_TO_LINEAR(TrapDouble(mPeakLevel, MIN_PeakLevel, MAX_PeakLevel));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ratio = 1.0;
|
ratio = 1.0;
|
||||||
@ -257,16 +212,8 @@ bool EffectNormalize::Process()
|
|||||||
wxString trackName = track->GetName();
|
wxString trackName = track->GetName();
|
||||||
|
|
||||||
float extent;
|
float extent;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
// Will compute a maximum
|
||||||
if (mUseLoudness)
|
extent = std::numeric_limits<float>::lowest();
|
||||||
// Loudness: use sum of both tracks.
|
|
||||||
// As a result, stereo tracks appear about 3 LUFS louder,
|
|
||||||
// as specified.
|
|
||||||
extent = 0;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
// Will compute a maximum
|
|
||||||
extent = std::numeric_limits<float>::lowest();
|
|
||||||
std::vector<float> offsets;
|
std::vector<float> offsets;
|
||||||
|
|
||||||
wxString msg;
|
wxString msg;
|
||||||
@ -287,12 +234,7 @@ bool EffectNormalize::Process()
|
|||||||
AnalyseTrack( channel, msg, progress, offset, extent2 );
|
AnalyseTrack( channel, msg, progress, offset, extent2 );
|
||||||
if ( ! bGoodResult )
|
if ( ! bGoodResult )
|
||||||
goto break2;
|
goto break2;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
extent = std::max( extent, extent2 );
|
||||||
if (mUseLoudness)
|
|
||||||
extent += extent2;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
extent = std::max( extent, extent2 );
|
|
||||||
offsets.push_back(offset);
|
offsets.push_back(offset);
|
||||||
// TODO: more-than-two-channels-message
|
// TODO: more-than-two-channels-message
|
||||||
msg = topMsg +
|
msg = topMsg +
|
||||||
@ -302,18 +244,6 @@ bool EffectNormalize::Process()
|
|||||||
// Compute the multiplier using extent
|
// Compute the multiplier using extent
|
||||||
if( (extent > 0) && mGain ) {
|
if( (extent > 0) && mGain ) {
|
||||||
mMult = ratio / extent;
|
mMult = ratio / extent;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
if(mUseLoudness) {
|
|
||||||
// PRL: See commit 9cbb67a for the origin of the next line,
|
|
||||||
// which has no effect because mMult is again overwritten. What
|
|
||||||
// was the intent?
|
|
||||||
|
|
||||||
// LUFS is defined as -0.691 dB + 10*log10(sum(channels))
|
|
||||||
mMult /= 0.8529037031;
|
|
||||||
// LUFS are related to square values so the multiplier must be the root.
|
|
||||||
mMult = sqrt(ratio / extent);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mMult = 1.0;
|
mMult = 1.0;
|
||||||
@ -373,12 +303,7 @@ void EffectNormalize::PopulateOrExchange(ShuttleGui & S)
|
|||||||
// which that is will depend on translation. So decide that here.
|
// which that is will depend on translation. So decide that here.
|
||||||
// (strictly we should count pixels, not characters).
|
// (strictly we should count pixels, not characters).
|
||||||
wxString prompt1 = _("Normalize peak amplitude to");
|
wxString prompt1 = _("Normalize peak amplitude to");
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
wxString prompt2 = _("Normalize loudness to");
|
|
||||||
wxString longerPrompt = ((prompt1.length() > prompt2.length()) ? prompt1 : prompt2) + " ";
|
|
||||||
#else
|
|
||||||
wxString longerPrompt = prompt1 + " ";
|
wxString longerPrompt = prompt1 + " ";
|
||||||
#endif
|
|
||||||
// Now make the checkbox.
|
// Now make the checkbox.
|
||||||
mGainCheckBox = S.AddCheckBox(longerPrompt,
|
mGainCheckBox = S.AddCheckBox(longerPrompt,
|
||||||
mGain);
|
mGain);
|
||||||
@ -398,11 +323,6 @@ void EffectNormalize::PopulateOrExchange(ShuttleGui & S)
|
|||||||
wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
|
wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
|
||||||
}
|
}
|
||||||
S.EndHorizontalLay();
|
S.EndHorizontalLay();
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
mUseLoudnessCheckBox = S.AddCheckBox(_("Use loudness instead of peak amplitude"),
|
|
||||||
mUseLoudness);
|
|
||||||
mUseLoudnessCheckBox->SetValidator(wxGenericValidator(&mGUIUseLoudness));
|
|
||||||
#endif
|
|
||||||
mStereoIndCheckBox = S.AddCheckBox(_("Normalize stereo channels independently"),
|
mStereoIndCheckBox = S.AddCheckBox(_("Normalize stereo channels independently"),
|
||||||
mStereoInd);
|
mStereoInd);
|
||||||
mStereoIndCheckBox->SetValidator(wxGenericValidator(&mStereoInd));
|
mStereoIndCheckBox->SetValidator(wxGenericValidator(&mStereoInd));
|
||||||
@ -412,10 +332,6 @@ void EffectNormalize::PopulateOrExchange(ShuttleGui & S)
|
|||||||
S.EndMultiColumn();
|
S.EndMultiColumn();
|
||||||
}
|
}
|
||||||
S.EndVerticalLay();
|
S.EndVerticalLay();
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
// To ensure that the UpdateUI on creation sets the prompts correctly.
|
|
||||||
mUseLoudness = !mGUIUseLoudness;
|
|
||||||
#endif
|
|
||||||
mCreating = false;
|
mCreating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,51 +367,27 @@ bool EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
|||||||
|
|
||||||
if(mGain)
|
if(mGain)
|
||||||
{
|
{
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
// Since we need complete summary data, we need to block until the OD tasks are done for this track
|
||||||
if(mUseLoudness)
|
// This is needed for track->GetMinMax
|
||||||
{
|
// TODO: should we restrict the flags to just the relevant block files (for selections)
|
||||||
CalcEBUR128HPF(track->GetRate());
|
while (ProjectFileManager::GetODFlags( *track )) {
|
||||||
CalcEBUR128HSF(track->GetRate());
|
// update the gui
|
||||||
if(mDC)
|
if (ProgressResult::Cancelled == mProgress->Update(
|
||||||
{
|
0, _("Waiting for waveform to finish computing...")) )
|
||||||
result = AnalyseTrackData(track, msg, progress, ANALYSE_LOUDNESS_DC, offset);
|
return false;
|
||||||
}
|
wxMilliSleep(100);
|
||||||
else
|
|
||||||
{
|
|
||||||
result = AnalyseTrackData(track, msg, progress, ANALYSE_LOUDNESS, offset);
|
|
||||||
offset = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EBU R128: z_i = mean square without root
|
|
||||||
extent = mSqSum / mCount.as_double();
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// set mMin, mMax. No progress bar here as it's fast.
|
||||||
|
auto pair = track->GetMinMax(mCurT0, mCurT1); // may throw
|
||||||
|
min = pair.first, max = pair.second;
|
||||||
|
|
||||||
|
if(mDC)
|
||||||
{
|
{
|
||||||
#endif
|
result = AnalyseTrackData(track, msg, progress, ANALYSE_DC, offset);
|
||||||
// Since we need complete summary data, we need to block until the OD tasks are done for this track
|
min += offset;
|
||||||
// This is needed for track->GetMinMax
|
max += offset;
|
||||||
// TODO: should we restrict the flags to just the relevant block files (for selections)
|
|
||||||
while (ProjectFileManager::GetODFlags( *track )) {
|
|
||||||
// update the gui
|
|
||||||
if (ProgressResult::Cancelled == mProgress->Update(
|
|
||||||
0, _("Waiting for waveform to finish computing...")) )
|
|
||||||
return false;
|
|
||||||
wxMilliSleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set mMin, mMax. No progress bar here as it's fast.
|
|
||||||
auto pair = track->GetMinMax(mCurT0, mCurT1); // may throw
|
|
||||||
min = pair.first, max = pair.second;
|
|
||||||
|
|
||||||
if(mDC)
|
|
||||||
{
|
|
||||||
result = AnalyseTrackData(track, msg, progress, ANALYSE_DC, offset);
|
|
||||||
min += offset;
|
|
||||||
max += offset;
|
|
||||||
}
|
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if(mDC)
|
else if(mDC)
|
||||||
{
|
{
|
||||||
@ -510,10 +402,7 @@ bool EffectNormalize::AnalyseTrack(const WaveTrack * track, const wxString &msg,
|
|||||||
min = -1.0, max = 1.0; // sensible defaults?
|
min = -1.0, max = 1.0; // sensible defaults?
|
||||||
offset = 0.0;
|
offset = 0.0;
|
||||||
}
|
}
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
extent = fmax(fabs(min), fabs(max));
|
||||||
if(!mUseLoudness)
|
|
||||||
#endif
|
|
||||||
extent = fmax(fabs(min), fabs(max));
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -540,9 +429,6 @@ bool EffectNormalize::AnalyseTrackData(const WaveTrack * track, const wxString &
|
|||||||
|
|
||||||
mSum = 0.0; // dc offset inits
|
mSum = 0.0; // dc offset inits
|
||||||
mCount = 0;
|
mCount = 0;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
mSqSum = 0.0; // rms init
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sampleCount blockSamples;
|
sampleCount blockSamples;
|
||||||
sampleCount totalSamples = 0;
|
sampleCount totalSamples = 0;
|
||||||
@ -565,12 +451,6 @@ bool EffectNormalize::AnalyseTrackData(const WaveTrack * track, const wxString &
|
|||||||
//Process the buffer.
|
//Process the buffer.
|
||||||
if(op == ANALYSE_DC)
|
if(op == ANALYSE_DC)
|
||||||
AnalyseDataDC(buffer.get(), block);
|
AnalyseDataDC(buffer.get(), block);
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
else if(op == ANALYSE_LOUDNESS)
|
|
||||||
AnalyseDataLoudness(buffer.get(), block);
|
|
||||||
else if(op == ANALYSE_LOUDNESS_DC)
|
|
||||||
AnalyseDataLoudnessDC(buffer.get(), block);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Increment s one blockfull of samples
|
//Increment s one blockfull of samples
|
||||||
s += block;
|
s += block;
|
||||||
@ -658,40 +538,6 @@ void EffectNormalize::AnalyseDataDC(float *buffer, size_t len)
|
|||||||
mCount += len;
|
mCount += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
/// @see AnalyseDataLoudnessDC
|
|
||||||
void EffectNormalize::AnalyseDataLoudness(float *buffer, size_t len)
|
|
||||||
{
|
|
||||||
float value;
|
|
||||||
for(decltype(len) i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
value = mR128HSF.ProcessOne(buffer[i]);
|
|
||||||
value = mR128HPF.ProcessOne(value);
|
|
||||||
mSqSum += ((double)value) * ((double)value);
|
|
||||||
}
|
|
||||||
mCount += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculates sample sum (for DC) and EBU R128 weighted square sum
|
|
||||||
/// (for loudness). This function has variants which only calculate
|
|
||||||
/// sum or square sum for performance improvements if only one of those
|
|
||||||
/// values is required.
|
|
||||||
/// @see AnalyseDataLoudness
|
|
||||||
/// @see AnalyseDataDC
|
|
||||||
void EffectNormalize::AnalyseDataLoudnessDC(float *buffer, size_t len)
|
|
||||||
{
|
|
||||||
float value;
|
|
||||||
for(decltype(len) i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
mSum += (double)buffer[i];
|
|
||||||
value = mR128HSF.ProcessOne(buffer[i]);
|
|
||||||
value = mR128HPF.ProcessOne(value);
|
|
||||||
mSqSum += ((double)value) * ((double)value);
|
|
||||||
}
|
|
||||||
mCount += len;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void EffectNormalize::ProcessData(float *buffer, size_t len, float offset)
|
void EffectNormalize::ProcessData(float *buffer, size_t len, float offset)
|
||||||
{
|
{
|
||||||
for(decltype(len) i = 0; i < len; i++) {
|
for(decltype(len) i = 0; i < len; i++) {
|
||||||
@ -700,56 +546,6 @@ void EffectNormalize::ProcessData(float *buffer, size_t len, float offset)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
// EBU R128 parameter sampling rate adaption after
|
|
||||||
// Mansbridge, Stuart, Saoirse Finn, and Joshua D. Reiss.
|
|
||||||
// "Implementation and Evaluation of Autonomous Multi-track Fader Control."
|
|
||||||
// Paper presented at the 132nd Audio Engineering Society Convention,
|
|
||||||
// Budapest, Hungary, 2012."
|
|
||||||
void EffectNormalize::CalcEBUR128HPF(float fs)
|
|
||||||
{
|
|
||||||
double f0 = 38.13547087602444;
|
|
||||||
double Q = 0.5003270373238773;
|
|
||||||
double K = tan(M_PI * f0 / fs);
|
|
||||||
|
|
||||||
mR128HPF.Reset();
|
|
||||||
|
|
||||||
mR128HPF.fNumerCoeffs[Biquad::B0] = 1.0;
|
|
||||||
mR128HPF.fNumerCoeffs[Biquad::B1] = -2.0;
|
|
||||||
mR128HPF.fNumerCoeffs[Biquad::B2] = 1.0;
|
|
||||||
|
|
||||||
mR128HPF.fDenomCoeffs[Biquad::A1] = 2.0 * (K * K - 1.0) / (1.0 + K / Q + K * K);
|
|
||||||
mR128HPF.fDenomCoeffs[Biquad::A2] = (1.0 - K / Q + K * K) / (1.0 + K / Q + K * K);
|
|
||||||
}
|
|
||||||
|
|
||||||
// EBU R128 parameter sampling rate adaption after
|
|
||||||
// Mansbridge, Stuart, Saoirse Finn, and Joshua D. Reiss.
|
|
||||||
// "Implementation and Evaluation of Autonomous Multi-track Fader Control."
|
|
||||||
// Paper presented at the 132nd Audio Engineering Society Convention,
|
|
||||||
// Budapest, Hungary, 2012."
|
|
||||||
void EffectNormalize::CalcEBUR128HSF(float fs)
|
|
||||||
{
|
|
||||||
double db = 3.999843853973347;
|
|
||||||
double f0 = 1681.974450955533;
|
|
||||||
double Q = 0.7071752369554196;
|
|
||||||
double K = tan(M_PI * f0 / fs);
|
|
||||||
|
|
||||||
double Vh = pow(10.0, db / 20.0);
|
|
||||||
double Vb = pow(Vh, 0.4996667741545416);
|
|
||||||
|
|
||||||
double a0 = 1.0 + K / Q + K * K;
|
|
||||||
|
|
||||||
mR128HSF.Reset();
|
|
||||||
|
|
||||||
mR128HSF.fNumerCoeffs[Biquad::B0] = (Vh + Vb * K / Q + K * K) / a0;
|
|
||||||
mR128HSF.fNumerCoeffs[Biquad::B1] = 2.0 * (K * K - Vh) / a0;
|
|
||||||
mR128HSF.fNumerCoeffs[Biquad::B2] = (Vh - Vb * K / Q + K * K) / a0;
|
|
||||||
|
|
||||||
mR128HSF.fDenomCoeffs[Biquad::A1] = 2.0 * (K * K - 1.0) / a0;
|
|
||||||
mR128HSF.fDenomCoeffs[Biquad::A2] = (1.0 - K / Q + K * K) / a0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void EffectNormalize::OnUpdateUI(wxCommandEvent & WXUNUSED(evt))
|
void EffectNormalize::OnUpdateUI(wxCommandEvent & WXUNUSED(evt))
|
||||||
{
|
{
|
||||||
UpdateUI();
|
UpdateUI();
|
||||||
@ -766,44 +562,10 @@ void EffectNormalize::UpdateUI()
|
|||||||
}
|
}
|
||||||
mWarning->SetLabel(wxT(""));
|
mWarning->SetLabel(wxT(""));
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
// Changing the prompts causes an unwanted UpdateUI event.
|
|
||||||
// This 'guard' stops that becoming an infinite recursion.
|
|
||||||
if (mUseLoudness != mGUIUseLoudness)
|
|
||||||
{
|
|
||||||
mUseLoudness = mGUIUseLoudness;
|
|
||||||
if (mUseLoudness)
|
|
||||||
{
|
|
||||||
FloatingPointValidator<double> vldLevel(2, &mLUFSLevel, NumValidatorStyle::ONE_TRAILING_ZERO);
|
|
||||||
vldLevel.SetRange(MIN_LUFSLevel, MAX_LUFSLevel);
|
|
||||||
mLevelTextCtrl->SetValidator(vldLevel);
|
|
||||||
/* i18n-hint: LUFS is a particular method for measuring loudnesss */
|
|
||||||
mLevelTextCtrl->SetName(_("Loudness LUFS"));
|
|
||||||
mLevelTextCtrl->SetValue(wxString::FromDouble(mLUFSLevel));
|
|
||||||
/* i18n-hint: LUFS is a particular method for measuring loudnesss */
|
|
||||||
mLeveldB->SetLabel(_("LUFS"));
|
|
||||||
mGainCheckBox->SetLabelText(_("Normalize loudness to"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FloatingPointValidator<double> vldLevel(2, &mPeakLevel, NumValidatorStyle::ONE_TRAILING_ZERO);
|
|
||||||
vldLevel.SetRange(MIN_PeakLevel, MAX_PeakLevel);
|
|
||||||
mLevelTextCtrl->SetValidator(vldLevel);
|
|
||||||
mLevelTextCtrl->SetName(_("Peak amplitude dB"));
|
|
||||||
mLevelTextCtrl->SetValue(wxString::FromDouble(mPeakLevel));
|
|
||||||
mLeveldB->SetLabel(_("dB"));
|
|
||||||
mGainCheckBox->SetLabelText(_("Normalize peak amplitude to"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Disallow level stuff if not normalizing
|
// Disallow level stuff if not normalizing
|
||||||
mLevelTextCtrl->Enable(mGain);
|
mLevelTextCtrl->Enable(mGain);
|
||||||
mLeveldB->Enable(mGain);
|
mLeveldB->Enable(mGain);
|
||||||
mStereoIndCheckBox->Enable(mGain);
|
mStereoIndCheckBox->Enable(mGain);
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
mUseLoudnessCheckBox->Enable(mGain);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Disallow OK/Preview if doing nothing
|
// Disallow OK/Preview if doing nothing
|
||||||
EnableApply(mGain || mDC);
|
EnableApply(mGain || mDC);
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
Dominic Mazzoni
|
Dominic Mazzoni
|
||||||
Vaughan Johnson (Preview)
|
Vaughan Johnson (Preview)
|
||||||
Max Maisel (Loudness)
|
|
||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
@ -71,17 +70,8 @@ private:
|
|||||||
bool AnalyseTrackData(const WaveTrack * track, const wxString &msg, double &progress,
|
bool AnalyseTrackData(const WaveTrack * track, const wxString &msg, double &progress,
|
||||||
AnalyseOperation op, float &offset);
|
AnalyseOperation op, float &offset);
|
||||||
void AnalyseDataDC(float *buffer, size_t len);
|
void AnalyseDataDC(float *buffer, size_t len);
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
void AnalyseDataLoudness(float *buffer, size_t len);
|
|
||||||
void AnalyseDataLoudnessDC(float *buffer, size_t len);
|
|
||||||
#endif
|
|
||||||
void ProcessData(float *buffer, size_t len, float offset);
|
void ProcessData(float *buffer, size_t len, float offset);
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
void CalcEBUR128HPF(float fs);
|
|
||||||
void CalcEBUR128HSF(float fs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OnUpdateUI(wxCommandEvent & evt);
|
void OnUpdateUI(wxCommandEvent & evt);
|
||||||
void UpdateUI();
|
void UpdateUI();
|
||||||
|
|
||||||
@ -90,19 +80,11 @@ private:
|
|||||||
bool mGain;
|
bool mGain;
|
||||||
bool mDC;
|
bool mDC;
|
||||||
bool mStereoInd;
|
bool mStereoInd;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
double mLUFSLevel;
|
|
||||||
bool mUseLoudness;
|
|
||||||
bool mGUIUseLoudness;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
double mCurT0;
|
double mCurT0;
|
||||||
double mCurT1;
|
double mCurT1;
|
||||||
float mMult;
|
float mMult;
|
||||||
double mSum;
|
double mSum;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
double mSqSum;
|
|
||||||
#endif
|
|
||||||
sampleCount mCount;
|
sampleCount mCount;
|
||||||
|
|
||||||
wxCheckBox *mGainCheckBox;
|
wxCheckBox *mGainCheckBox;
|
||||||
@ -111,12 +93,6 @@ private:
|
|||||||
wxStaticText *mLeveldB;
|
wxStaticText *mLeveldB;
|
||||||
wxStaticText *mWarning;
|
wxStaticText *mWarning;
|
||||||
wxCheckBox *mStereoIndCheckBox;
|
wxCheckBox *mStereoIndCheckBox;
|
||||||
#ifdef EXPERIMENTAL_R128_NORM
|
|
||||||
wxCheckBox *mUseLoudnessCheckBox;
|
|
||||||
|
|
||||||
Biquad mR128HSF;
|
|
||||||
Biquad mR128HPF;
|
|
||||||
#endif
|
|
||||||
bool mCreating;
|
bool mCreating;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user