1
0
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:
Max Maisel 2019-03-15 16:22:53 +01:00
parent e439e8f4c7
commit c3d25cfb44
3 changed files with 22 additions and 287 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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;