7#include "metrics/hart_metric_query.hpp"
8#include "metrics/hart_metrics_common.hpp"
10#include "metrics/hart_snr.hpp"
132template <
typename SampleType>
133MetricQuery<
double>
snra (
const AudioBuffer<SampleType>& estimatedBufferAtNativeSR,
const AudioBuffer<SampleType>& referenceBufferAtHighSR)
135 if (! estimatedBufferAtNativeSR.hasSampleRate() || estimatedBufferAtNativeSR.getSampleRateHz() < 0.0 || floatsEqual (estimatedBufferAtNativeSR.getSampleRateHz(), 0.0))
138 if (! referenceBufferAtHighSR.hasSampleRate() || referenceBufferAtHighSR.getSampleRateHz() < 0.0 || floatsEqual (referenceBufferAtHighSR.getSampleRateHz(), 0.0))
141 if (referenceBufferAtHighSR.getSampleRateHz() < estimatedBufferAtNativeSR.getSampleRateHz() || floatsEqual (referenceBufferAtHighSR.getSampleRateHz(), estimatedBufferAtNativeSR.getSampleRateHz()))
144 if (floatsNotEqual (estimatedBufferAtNativeSR.getLengthSeconds(), referenceBufferAtHighSR.getLengthSeconds()))
148 if (estimatedBufferAtNativeSR.getNumChannels() != referenceBufferAtHighSR.getNumChannels())
151 const double nativeSampleRateHz = estimatedBufferAtNativeSR.getSampleRateHz();
152 const std::shared_ptr<AudioBuffer<SampleType>> referenceBufferAtNativeSR =
153 std::make_shared<AudioBuffer<SampleType>> (referenceBufferAtHighSR.resample (nativeSampleRateHz));
156 hassert (estimatedBufferAtNativeSR.getNumFrames() == referenceBufferAtNativeSR->getNumFrames());
159 hassert (estimatedBufferAtNativeSR.getNumChannels() == referenceBufferAtNativeSR->getNumChannels());
161 MetricQuery<
double>::SingleChannelMetricEvaluator evaluator =
162 [&estimatedBufferAtNativeSR, referenceBufferAtNativeSR]
163 (size_t channel,
Slice slice,
Unit requestedUnit)
166 hassert (referenceBufferAtNativeSR !=
nullptr);
169 hassert (estimatedBufferAtNativeSR.getNumFrames() == referenceBufferAtNativeSR->getNumFrames());
172 hassert (estimatedBufferAtNativeSR.getNumChannels() == referenceBufferAtNativeSR->getNumChannels());
174 if (channel >= estimatedBufferAtNativeSR.getNumChannels())
181 const auto sliceFrameIndices = estimatedBufferAtNativeSR.getFrameIndices (slice);
182 const size_t sliceStart = sliceFrameIndices.first;
183 const size_t sliceStop = sliceFrameIndices.second;
184 hassert (sliceStop > sliceStart);
185 hassert (sliceStop <= estimatedBufferAtNativeSR.getNumFrames());
187 const size_t numFrames = sliceStop - sliceStart;
193 const SampleType* referenceChannelData = (*referenceBufferAtNativeSR)[channel] + sliceStart;
194 const SampleType* estimatedChannelData = estimatedBufferAtNativeSR[channel] + sliceStart;
196 for (size_t frame = 0; frame < numFrames; ++frame)
198 const double x =
static_cast<
double> (referenceChannelData[frame]);
199 const double y =
static_cast<
double> (estimatedChannelData[frame]);
200 const double noise = x - y;
202 signalEnergy
+= x * x;
203 aliasingNoiseEnergy
+= noise * noise;
214 switch (requestedUnit)
225 hassert (estimatedBufferAtNativeSR.getNumChannels() == referenceBufferAtHighSR.getNumChannels());
226 const size_t numChannels = estimatedBufferAtNativeSR.getNumChannels();
228 std::move (evaluator)
,
Implements Kahan algorithm for floating point accumulations.
SampleType getValue() const
AccurateSum & operator+=(SampleType value)
Adds a value to a sum, tracking the potential floating point error.
Thrown when a numbers of channels is mismatched.
Thrown when a container index is out of range.
Manages the metrics calculations.
MetricQuery(SingleChannelMetricEvaluator evaluator, size_t totalNumChannels, std::vector< size_t > &&defaultChannelsToProcess)
Create a metric query object for a metric that operates on one channel at a time.
Thrown when sample rate is mismatched or invalid.
Thrown when an unexpected container size is encountered.
Thrown when some metric is requested to return a value in an unsupported unit.
#define hassert(condition)
Triggers a HartAssertException if the condition is false
#define HART_THROW_OR_RETURN(ExceptionType, message, returnValue)
Throws an exception if HART_DO_NOT_THROW_EXCEPTIONS is set, prints a message and returns a specified ...
MetricQuery< double > snra(const AudioBuffer< SampleType > &estimatedBufferAtNativeSR, const AudioBuffer< SampleType > &referenceBufferAtHighSR)
Calculates signal-to-aliasing-noise ratio (a.k.a. SNRA, SNRa or sometimes SANR)
FloatType nan()
Returns a quiet NaN value for the given floating-point type.
constexpr double inf
Infinity.
static SampleType powerToDecibels(SampleType valueLinear)
Converts linear value (power) to dB.
static SampleType floatsEqual(SampleType a, SampleType b, SampleType epsilon=(SampleType) 1e-8)
Compares two floating point numbers within a given tolerance.
Unit
Represents a physical unit.
@ dB
Value of something in decibels. Can represent voltage, power, or a domain-specific unit like "LUFS" o...
@ native
Default (native) unit of whatever returns some value.
Helpers to generate common default channel subsets.
static std::vector< size_t > allChannels(size_t numChannels)
Represents a slice of analysis data.