153 if (numChannels <= 0 || numSamples <= 0)
158 if (!std::isfinite(sampleRate) || sampleRate <= 0.0)
164 T maxAbsInput = T(0);
165 for (
int channel = 0; channel < numChannels; ++channel)
168 for (
int i = 0; i < numSamples; ++i)
170 const T sample = samples[i];
171 if (!std::isfinite(sample))
176 maxAbsInput = std::max(maxAbsInput, std::abs(sample));
180 const T measured = measureIntegrated(audio, sampleRate);
181 if (!meter_.isMeasurementValid())
186 const T inputTruePeak = measureTruePeakLinear(audio);
187 if (!std::isfinite(measured) || !std::isfinite(inputTruePeak)
188 || inputTruePeak < T(0))
194 if (measured <= kMeterFloorLUFS || !(inputTruePeak > T(0)))
199 out.
outTruePeakDb = linearToDecibels(inputTruePeak, T(-100));
203 const T target = targetLUFS_.load(std::memory_order_relaxed);
204 const T ceilingDb = ceilingDb_.load(std::memory_order_relaxed);
205 const T requestedGainDb = target - measured;
206 const T requestedLinear = decibelsToLinear(requestedGainDb);
207 const T ceilingLinear = decibelsToLinear(ceilingDb);
208 const T ceilingSafeLinear =
static_cast<T
>(
209 static_cast<double>(ceilingLinear) * (1.0 - kCeilingAimMargin)
210 /
static_cast<double>(inputTruePeak));
211 const T appliedLinear = std::min(requestedLinear, ceilingSafeLinear);
212 const T appliedGainDb = linearToDecibels(appliedLinear, T(0));
214 if (!std::isfinite(requestedGainDb) || !std::isfinite(requestedLinear)
215 || !std::isfinite(ceilingLinear)
216 || !std::isfinite(ceilingSafeLinear)
217 || !std::isfinite(appliedLinear) || !(appliedLinear > T(0))
218 || !std::isfinite(appliedGainDb)
219 ||
static_cast<long double>(maxAbsInput)
220 >
static_cast<long double>(std::numeric_limits<T>::max())
221 /
static_cast<long double>(appliedLinear))
233 for (
int channel = 0; channel < numChannels; ++channel)
236 for (
int i = 0; i < numSamples; ++i)
237 samples[i] =
static_cast<T
>(samples[i] * appliedLinear);
240 out.
outLUFS = measureIntegrated(audio, sampleRate);
241 out.
outTruePeakDb = linearToDecibels(measureTruePeakLinear(audio), T(-100));
266 [[nodiscard]] T measureIntegrated(
const AudioBuffer<T, MaxChannels>& audio,