10#include "metrics/hart_metric_query.hpp"
11#include "metrics/hart_metrics_common.hpp"
26 if (smoothingCents <= 0.0)
29 MetricQuery<
double>::SingleChannelMetricEvaluator evaluator =
30 [&spectrum, smoothingCents]
31 (size_t channel,
const Slice& slice,
Unit requestedUnit)
38 const size_t startBin = std::max<size_t> (1, binIndices.first);
39 const size_t stopBin = binIndices.second;
41 if (slice
.isEmpty() || stopBin - startBin == 0)
53 std::vector<LogLogPoint> logLogPoints;
57 double currentBandEndHz = currentBandStartHz * bandRatio;
59 while (currentBandEndHz <= stopFrequencyHz)
62 size_t numCurrentBandBins = 0;
64 for (size_t bin = startBin; bin < stopBin; ++bin)
68 if (frequencyHz < currentBandStartHz)
71 if (frequencyHz >= currentBandEndHz)
78 if (numCurrentBandBins > 0)
80 const double binMeanPower = bandPower
.getValue() /
static_cast<
double> (numCurrentBandBins);
86 const double centreFrequencyHz = std::sqrt (currentBandStartHz * currentBandEndHz);
88 logLogPoints.push_back ({
89 std::log (centreFrequencyHz),
90 std::log (binMeanPower)
94 currentBandStartHz = currentBandEndHz;
95 currentBandEndHz = currentBandStartHz * bandRatio;
102 for (
const LogLogPoint logLogPoint : logLogPoints)
104 sumX
+= logLogPoint.logFrequency;
105 sumY
+= logLogPoint.logPower;
108 const double meanX = sumX
.getValue() / logLogPoints.size();
109 const double meanY = sumY
.getValue() / logLogPoints.size();
114 for (
const LogLogPoint logLogPoint : logLogPoints)
116 const double dx = logLogPoint.logFrequency - meanX;
117 const double dy = logLogPoint.logPower - meanY;
119 covariance
+= dx * dy;
120 varianceX
+= dx * dx;
126 constexpr double threeDb = 3.010299956639812;
128 switch (requestedUnit)
145 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.
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.
Frequency-domain representation of a multi-channel audio signal.
double getSampleRateHz() const
Returns sample rate in Hz.
std::pair< size_t, size_t > getBinIndices(const Slice &slice) const
Returns a pair of indices representing a provided slice.
double getBinFrequencyHz(size_t binIndex) const
Returns frequency corresponding to a bin index.
size_t getNumBins() const
Returns number of frequency bins per channel.
std::complex< double > getBinValue(size_t channel, size_t binIndex) const
Returns complex value of a frequency bin, by bin index.
size_t getNumChannels() const
Returns number of channels.
Thrown when some metric is requested to return a value in an unsupported unit.
Thrown when an inappropriate value is encountered.
#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 > spectralLogLogSlope(const Spectrum &spectrum, double smoothingCents=1200.0)
Calculates slope of the spectrum in logX-logY domain.
FloatType nan()
Returns a quiet NaN value for the given floating-point type.
static SampleType floatsEqual(SampleType a, SampleType b, SampleType epsilon=(SampleType) 1e-8)
Compares two floating point numbers within a given tolerance.
double centsToRatio(double cents)
Converts frequency difference in cents to frequence ratio.
Unit
Represents a physical unit.
@ native
Default (native) unit of whatever returns some value.
@ dB_per_octave
Slope of something in decibels per octave.
Helpers to generate common default channel subsets.
static std::vector< size_t > allChannels(size_t numChannels)
Represents a slice of analysis data.