8#include "metrics/hart_metric_query.hpp"
9#include "metrics/hart_metrics_common.hpp"
63template <
typename SampleType>
64MetricQuery<
double>
snr (
const AudioBuffer<SampleType>& signalPlusNoise,
const AudioBuffer<SampleType>& signal)
66 if (! signalPlusNoise.hasSampleRate() || signalPlusNoise.getSampleRateHz() < 0.0 || floatsEqual (signalPlusNoise.getSampleRateHz(), 0.0))
69 if (! signal.hasSampleRate() || signal.getSampleRateHz() < 0.0 || floatsEqual (signal.getSampleRateHz(), 0.0))
72 if (floatsNotEqual (signalPlusNoise.getSampleRateHz(), signal.getSampleRateHz()))
75 MetricQuery<
double>::SingleChannelMetricEvaluator evaluator =
76 [&signalPlusNoise, &signal]
77 (size_t channel,
Slice slice,
Unit requestedUnit)
80 const double sampleRateHz = signal.getSampleRateHz();
82 if (channel >= signalPlusNoise.getNumChannels())
85 if (channel >= signal.getNumChannels())
91 const auto sliceFrameIndices = signal.getFrameIndices (slice);
92 const size_t sliceStart = sliceFrameIndices.first;
93 const size_t sliceStop = sliceFrameIndices.second;
94 hassert (sliceStop > sliceStart);
95 hassert (sliceStop <= signal.getNumFrames());
97 const size_t numFrames = sliceStop - sliceStart;
103 const SampleType* signalChannelData = signal[channel] + sliceStart;
104 const SampleType* signalPlusNoiseChannelData = signalPlusNoise[channel] + sliceStart;
106 for (size_t frame = 0; frame < numFrames; ++frame)
108 const double s =
static_cast<
double> (signalChannelData[frame]);
109 const double spn =
static_cast<
double> (signalPlusNoiseChannelData[frame]);
110 const double n = spn - s;
112 signalEnergy
+= s * s;
113 noiseEnergy
+= n * n;
125 switch (requestedUnit)
136 const size_t numChannels = std::min (signal.getNumChannels(), signalPlusNoise.getNumChannels());
138 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 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 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 > snr(const AudioBuffer< SampleType > &signalPlusNoise, const AudioBuffer< SampleType > &signal)
Calculates signal-to-noise ratio (SNR)
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.