22#include <wx/simplebook.h>
27#include "../ProjectFileManager.h"
30#include "../widgets/valnum.h"
37 {
XO(
"perceived loudness") },
56{
XO(
"Loudness Normalization") };
79 return XO(
"Sets the loudness of one or more tracks");
84 return L
"Loudness_Normalization";
109 bool bGoodResult =
true;
110 auto topMsg =
XO(
"Normalizing Loudness...\n");
115 for (
auto pTrack : outputs.Get().Selected<
WaveTrack>()) {
117 double trackStart = pTrack->GetStartTime();
118 double trackEnd = pTrack->GetEndTime();
122 const double curT0 = std::max(trackStart,
mT0);
129 auto trackName = pTrack->GetName();
134 topMsg +
XO(
"Analyzing: %s").Format(trackName);
136 const auto channels = pTrack->Channels();
137 auto nChannels =
mStereoInd ? 1 : channels.size();
141 std::optional<EBUR128> loudnessProcessor;
145 loudnessProcessor.emplace(
mCurRate, nChannels);
147 curT0, curT1, 0, &*loudnessProcessor))
155 for (
const auto pChannel : channels) {
156 if (!
GetTrackRMS(*pChannel, curT0, curT1, RMS[idx]))
170 extent = loudnessProcessor->IntegrativeLoudness();
177 extent =
sqrt((RMS[0] * RMS[0] + RMS[1] * RMS[1]) / 2.0);
184 float mult = ratio / extent;
189 if (nChannels == 1 &&
199 if (!
ProcessOne(track, nChannels, curT0, curT1, mult,
nullptr)) {
207 for (
const auto pChannel : channels)
208 if (!(bGoodResult = processOne(*pChannel)))
212 if (!(bGoodResult = processOne(*pTrack)))
230 S.StartVerticalLay(0);
232 S.StartMultiColumn(2, wxALIGN_CENTER);
234 S.StartVerticalLay(
false);
236 S.StartHorizontalLay(wxALIGN_LEFT,
false);
238 S.AddVariableText(
XO(
"&Normalize"),
false,
239 wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
247 .AddVariableText(
XO(
"t&o"),
false,
248 wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
256 S.StartNotebookPage({});
258 S.StartHorizontalLay(wxALIGN_LEFT,
false);
262 .Name(
XO(
"Loudness LUFS") )
263 .
Validator<FloatingPointValidator<double>>(
265 NumValidatorStyle::ONE_TRAILING_ZERO,
267 .AddTextBox( {}, L
"", 10);
271 .AddVariableText(
XO(
"LUFS"),
false,
272 wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
274 S.EndHorizontalLay();
278 S.StartNotebookPage({});
280 S.StartHorizontalLay(wxALIGN_LEFT,
false);
283 .Name(
XO(
"RMS dB") )
284 .
Validator<FloatingPointValidator<double>>(
286 NumValidatorStyle::ONE_TRAILING_ZERO,
288 .AddTextBox( {}, L
"", 10);
291 .AddVariableText(
XO(
"dB"),
false,
292 wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
294 S.EndHorizontalLay();
302 .AddVariableText( {},
false,
303 wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT);
305 S.EndHorizontalLay();
309 .AddCheckBox(
XXO(
"Normalize &stereo channels independently"),
313 .Validator<wxGenericValidator>( &
mDualMono )
314 .AddCheckBox(
XXO(
"&Treat mono as dual-mono (recommended)"),
333 wxCommandEvent dummy;
354 bool stereoTrackFound =
false;
355 double maxSampleRate = 0;
360 maxSampleRate = std::max(maxSampleRate, track->GetRate());
363 if(track->IsLeader())
364 stereoTrackFound =
true;
382 const double curT0,
const double curT1,
float &rms)
385 float _rms = track.
GetRMS(curT0, curT1);
397 const double curT0,
const double curT1,
const float mult,
423 const size_t remainingLen = (
end - s).as_size_t();
424 blockLen = blockLen > remainingLen ? remainingLen : blockLen;
428 if (pLoudnessProcessor) {
508 return setOne(track);
511 if (!setOne(*channel))
528 mChoice->GetValidator()->TransferFromWindow();
541 if (!
mUIParent->TransferDataFromWindow())
XXO("&Cut/Copy/Paste Toolbar")
static const EnumValueSymbol kNormalizeTargetStrings[EffectLoudness::nAlgos]
size_t limitSampleBufferSize(size_t bufferSize, sampleCount limit)
TranslatableStrings Msgids(const EnumValueSymbol strings[], size_t nStrings)
Convenience function often useful when adding choice controls.
void reinit(Integral count, bool initialize=false)
Generates EffectParameterMethods overrides from variadic template arguments.
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
Implements EBU-R128 loudness measurement.
void ProcessSampleFromChannel(float x_in, size_t channel) const
void SetLinearEffectFlag(bool linearEffectFlag)
std::shared_ptr< TrackList > mTracks
static bool EnableApply(wxWindow *parent, bool enable=true)
Enable or disable the Apply button of the dialog that contains parent.
bool TotalProgress(double frac, const TranslatableString &={}) const
int GetNumWaveTracks() const
Performs effect computation.
An Effect to bring the loudness level up to a chosen level.
bool Process(EffectInstance &instance, EffectSettings &settings) override
size_t mTrackBufferCapacity
wxCheckBox * mDualMonoCheckBox
bool AnalyseBufferBlock(EBUR128 &loudnessProcessor)
static const ComponentInterfaceSymbol Symbol
wxCheckBox * mStereoIndCheckBox
wxWeakRef< wxWindow > mUIParent
ComponentInterfaceSymbol GetSymbol() const override
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
void OnUpdateUI(wxCommandEvent &evt)
const EffectParameterMethods & Parameters() const override
TranslatableString GetDescription() const override
bool TransferDataToWindow(const EffectSettings &settings) override
void AllocBuffers(TrackList &outputs)
EffectType GetType() const override
Type determines how it behaves.
static constexpr EffectParameter StereoInd
static constexpr EffectParameter LUFSLevel
bool ProcessBufferBlock(float mult)
static constexpr EffectParameter RMSLevel
static constexpr EffectParameter DualMono
virtual ~EffectLoudness()
void LoadBufferBlock(WaveChannel &track, size_t nChannels, sampleCount pos, size_t len)
bool TransferDataFromWindow(EffectSettings &settings) override
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
Add controls to effect panel; always succeeds.
static constexpr EffectParameter NormalizeTo
bool ProcessOne(WaveChannel &track, size_t nChannels, double curT0, double curT1, float mult, EBUR128 *pLoudnessProcessor)
bool StoreBufferBlock(WaveChannel &track, size_t nChannels, sampleCount pos, size_t len)
void OnChoice(wxCommandEvent &evt)
TranslatableString mProgressMsg
static bool GetTrackRMS(WaveChannel &track, double curT0, double curT1, float &rms)
Use this object to copy the input tracks to tentative outputTracks.
Hold values to send to effect output meters.
Interface for manipulations of an Effect's settings.
virtual void Reset(Effect &effect) const =0
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
auto Selected() -> TrackIterRange< TrackType >
Holds a msgid for the translation catalog; may also bind format arguments.
A Validator is an object which checks whether a wxVariant satisfies a certain criterion....
float GetRMS(double t0, double t1, bool mayThrow=true) const
Get root-mean-square.
size_t GetBestBlockSize(sampleCount t) const
A hint for sizing of well aligned fetches.
A Track that contains audio waveform data.
sampleCount TimeToLongSamples(double t0) const
Positions or offsets within audio files need a wide type.
bool IsMono(const Channel &channel)
Whether the channel is mono.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
BuiltinEffectsModule::Registration< EffectLoudness > reg
__finl float_x4 __vecc sqrt(const float_x4 &a)
const Type min
Minimum value.
const Type max
Maximum value.
Externalized state of a plug-in.