|
HART
0.2.0
High level Audio Regression and Testing
|
Common audio-related metrics. More...
Classes | |
| class | MetricQuery< ValueType > |
| Manages the metrics calculations. More... | |
Functions | |
| template<typename SampleType > | |
| MetricQuery< double > | centreTime (const ImpulseResponse< SampleType > &ir) |
| Calculates the centre time of an impulse response. | |
| template<typename SampleType > | |
| MetricQuery< double > | channelCorrelation (const AudioBuffer< SampleType > &buffer) |
| Calculates zero-lag normalized cross-correlation between two channels of an audio buffer. | |
| template<typename SampleType > | |
| MetricQuery< double > | crestFactor (const AudioBuffer< SampleType > &buffer) |
| Calculates linear crest factor for a single channel of an audio buffer. | |
| template<typename SampleType > | |
| MetricQuery< double > | esr (const AudioBuffer< SampleType > &referenceBuffer, const AudioBuffer< SampleType > &estimatedBuffer) |
| Calculates error-to-signal ratio (ESR) | |
| MetricQuery< double > | interpolatedPeakFrequency (const Spectrum &spectrum) |
| Returns the center frequency of the loudest FFT bin. | |
| template<typename SampleType > | |
| MetricQuery< double > | lagAtMaxCrossCorrelation (const AudioBuffer< SampleType > &bufferA, const AudioBuffer< SampleType > &bufferB, double maxLagSeconds, double minAbsBestCorrelation=0.5, CorrelationSearchMode searchMode=bestAbsoluteCorrelation) |
| Calculates lag corresponding to maximum normalized cross-correlation between two audio buffers. | |
| MetricQuery< double > | logSpectralDistance (const Spectrum &spectrumA, const Spectrum &spectrumB, Normalise normaliseLevels=Normalise::no, double smoothingCents=100.0) |
| Calculates difference between two spectra in log-frequency domain. | |
| MetricQuery< double > | loudestBinFrequency (const Spectrum &spectrum) |
| Returns the center frequency of the loudest FFT bin. | |
| MetricQuery< double > | loudestBinMagnitude (const Spectrum &spectrum) |
| Calculates the magnitude of the loudest FFT bin. | |
| template<typename SampleType > | |
| MetricQuery< double > | maxCrossCorrelation (const AudioBuffer< SampleType > &bufferA, const AudioBuffer< SampleType > &bufferB, double maxLagSeconds, CorrelationSearchMode searchMode=bestAbsoluteCorrelation) |
| Calculates maximum normalized cross-correlation between two audio buffers. | |
| MetricQuery< double > | quinns2 (const Spectrum &spectrum) |
| Returns somewhat accurate loudest frequency in the spectrum. | |
| template<typename SampleType > | |
| MetricQuery< double > | rms (const AudioBuffer< SampleType > &buffer) |
| Calculates root mean square (RMS) of a signal. | |
| template<typename SampleType > | |
| MetricQuery< double > | rt60 (const ImpulseResponse< SampleType > &ir, RT60::Method method=RT60::Method::edt) |
| Estimates the RT60 reverberation time of an impulse response. | |
| template<typename SampleType > | |
| MetricQuery< double > | samplePeak (const AudioBuffer< SampleType > &audioBuffer) |
| Calculates Sample Peak of an audio buffer. | |
| template<typename SampleType > | |
| MetricQuery< double > | snr (const AudioBuffer< SampleType > &signalPlusNoise, const AudioBuffer< SampleType > &signal) |
| Calculates signal-to-noise ratio (SNR) | |
| template<typename SampleType > | |
| 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) | |
| MetricQuery< double > | spectralCentroid (const Spectrum &spectrum, SpectralCentroid::Weighting weighting=SpectralCentroid::Weighting::magnitude) |
| Calculates spectral centroid. | |
| MetricQuery< double > | spectralFlatness (const Spectrum &spectrum, double floorLinear=1e-16) |
| Calculates spectral flatness, also known as Wiener entropy, or tonality coefficient. | |
| MetricQuery< double > | spectralLogLogSlope (const Spectrum &spectrum, double smoothingCents=1200.0) |
| Calculates slope of the spectrum in logX-logY domain. | |
| MetricQuery< double > | thd (const Spectrum &spectrum, THD::ExperimentSetup experimentSetup) |
| Calculates the total harmonic distortion (THD) of a spectrum. | |
| template<typename SampleType > | |
| MetricQuery< double > | truePeak (const AudioBuffer< SampleType > &audioBuffer, Oversampling oversamplingRatio=Oversampling::x4, typename TruePeak< SampleType >::FilterQuality filterQuality=TruePeak< SampleType >::FilterQuality::low) |
| Estimates true peak (inter-sample peak) level. | |
| template<typename SampleType > | |
| MetricQuery< double > | zcr (const AudioBuffer< SampleType > &buffer) |
| Calculates zero-crossing rate (ZCR) of a signal. | |
Common audio-related metrics.
| MetricQuery< double > centreTime | ( | const ImpulseResponse< SampleType > & | ir | ) |
Calculates the centre time of an impulse response.
Centre time (center time) is the energy-weighted mean arrival time of the impulse response. It describes where the energy of the response is centred in time: responses with more energy occurring later have a larger centre time. Can be used to verify shape of the decay, in combination with hart::rt60().
Calculated as:
\[ T_s=\frac{\sum_{n=0}^{N-1} t_n h[n]^2} {\sum_{n=0}^{N-1} h[n]^2} \]
(T_s = sum(t_n * h[n]^2) / sum(h[n]^2)),
where \(h[n]\) is the impulse response sample, and \(t_n\) is its time position (offset) in seconds.
Supported units are Unit::seconds, Unit::native (same as seconds) and Unit::frames. If Unit::frames is requested, the result will be a fractional value.
The result is NaN if the impulse response contains no energy.
| SampleType | Floating-point sample type of the impulse response. |
| ir | Impulse response to analyse. |
NaN. Definition at line 50 of file hart_centre_time.hpp.
| MetricQuery< double > channelCorrelation | ( | const AudioBuffer< SampleType > & | buffer | ) |
Calculates zero-lag normalized cross-correlation between two channels of an audio buffer.
Operates per specified pairs of channels, use a reducer to get a scalar value (see Reducers). If custom channel subset is not specified via ch(), defaults to a set of all unique unordered channel pairs, e.g. {{0, 1}} for stereo buffer, or {{0, 1}, {0, 2}, {1, 2}, {1, 3}, {2, 3}} for 3-channel buffer. A specific order of pairs is not guaranteed, unless you explicitly pass a custom list of channel pairs via ch().
Returns a unitless value, suppoert Unit::none and Unit::native, which are the same here, so there's no need to request any unit with a chained as() call.
Usage examples
Be careful when you want to specify only one channel pair:
Uses the normalized cross-correlation formula:
\[ \rho = \frac{\sum_n x[n]\,y[n]} {\sqrt{\left(\sum_n x[n]^2\right)\left(\sum_n y[n]^2\right)}} \]
(sum (x[n] * y[n]) / sqrt (sum (x[n]^2) * sum (y[n]^2)))
where x and y are the selected channels of the same buffer.
The returned value is in the range [-1, 1]:
1.0 means perfectly correlated channels0.0 means no linear correlation-1.0 means perfectly inverted polarityThe function returns NaN if correlation is undefined, such as when:
| buffer | Input audio buffer |
MetricQuery, which calculates normalized correlation coefficient per pair of channels, or NaN if correlation is undefined | SampleType | Floating point sample type, typically float or double |
| hart::IndexError | if either channel index is out of bounds |
Definition at line 70 of file hart_channel_correlation.hpp.
| MetricQuery< double > crestFactor | ( | const AudioBuffer< SampleType > & | buffer | ) |
Calculates linear crest factor for a single channel of an audio buffer.
Crest factor is defined as the ratio between the absolute peak value and RMS value:
\[ \frac{\max_n \left|x[n]\right|}{\sqrt{\frac{1}{N}\sum_n x[n]^2}} \]
(max (abs (x[n])) / sqrt ((1 / N) * sum (x[n]^2)))
Calculates values independently for each channel. Use a reducer to get a scalar value (see Reducers). Supports Unit::linear (default) and Unit::dB units. Decibel conversion is performed as 20 * log10 (x), i.e. the amplitude-ratio form, see hart::ratioToDecibels().
Usage example:
| buffer | Input audio buffer |
MetricQuery, which calculates crest factor in linear ratio units or dBNaN if the audio buffer contains zero frames.inf if the selected channel is silent, making RMS equal to (or close to) zero. | SampleType | Floating point sample type of the audio buffer, typically float or double |
| hart::IndexError | if the channel index is out of bounds, or slice boundary is out of range |
Definition at line 56 of file hart_crest_factor.hpp.
| MetricQuery< double > esr | ( | const AudioBuffer< SampleType > & | referenceBuffer, |
| const AudioBuffer< SampleType > & | estimatedBuffer | ||
| ) |
Calculates error-to-signal ratio (ESR)
ESR is a useful way to express the degree of similarity between two signals or waveforms, calculated as:
\[ ESR=\frac{\sum_{k=0}^{N-1} (x - y) ^ 2}{\sum_{k=0}^{N-1} x^2}$$ \]
(sum ((x - y) ** 2) / sum (x ** 2))
Where x is a signal represented by referenceBuffer and y is represented by estimatedBuffer. It's a ratio, so appropriate units are Unit::native and Unit::ratio. ESR = 0 means two signals are identical.
| referenceBuffer | A buffer representing x in the formula above |
| estimatedBuffer | A buffer representing y in the formula above |
MetricQuery, which calculates per-channel ESR values Definition at line 35 of file hart_esr.hpp.
|
inline |
Returns the center frequency of the loudest FFT bin.
Finds the maximum-magnitude FFT bin independently for each channel. Use reducers to combine multi-channel results (see Reducers).
Supports Unit::Hz (native/default) unit, so requesting a unit explicitly via MetricQuery::as() is not required.
This metric operates on FFT bins exactly as stored in the Spectrum. In a not-so-likely event where multiple bins have exactly the same magnitube, the lowest frequency will be returned. This is not intended for precise pitch tracking, but still useful for some types of tests, based around looking for peaks in a band of frequencies, but not a specific frequency.
For more precise peak frequency estimation, consider using Quinn's second estimator (hart::quinns2() metric) instead.
Usage examples:
| spectrum | Input frequency-domain spectrum |
| hart::UnitError | if unsupported unit is requested |
Definition at line 58 of file hart_interpolated_peak_frequency.hpp.
| MetricQuery< double > lagAtMaxCrossCorrelation | ( | const AudioBuffer< SampleType > & | bufferA, |
| const AudioBuffer< SampleType > & | bufferB, | ||
| double | maxLagSeconds, | ||
| double | minAbsBestCorrelation = 0.5, |
||
| CorrelationSearchMode | searchMode = bestAbsoluteCorrelation |
||
| ) |
Calculates lag corresponding to maximum normalized cross-correlation between two audio buffers.
Searches for the lag producing the strongest normalized cross-correlation independently for each selected pair of channels.
Cross-correlation is calculated using the following formula:
\[ \frac{\sum_n x[n]\,y[n+k]} {\sqrt{ \left(\sum_n x[n]^2\right) \left(\sum_n y[n+k]^2\right) }} \]
(sum (x[n] * y[n + k]) / sqrt (sum (x[n]^2) * sum (y[n + k]^2)))
where:
x[n] is the left-hand-side signaly[n + k] is the right-hand-side signal shifted by lag kk is searched in the range [-maxLag, +maxLag]Positive lag means that bufferB is delayed relative to bufferA.
Depending on searchMode, the metric either:
Correlation is calculated independently for each selected pair of channels. Use a reducer to combine multiple lag values into a scalar.
Supports Unit::frames (default/native) and Unit::seconds. For conversion to seconds, it uses sample rate metadata contained in the provided buffers.
Usage examples:
Notes:
NaN.| bufferA | Left-hand-side audio buffer |
| bufferB | Right-hand-side audio buffer |
| maxLagSeconds | Maximum lag to search in seconds |
| minAbsBestCorrelation | If best correlation (rectified) is under this value, then signals will be considered to not have valid overlap, and result will be NaN |
| searchMode | Controls how the best lag is selected |
| SampleType | Floating point sample type, typically float or double |
| hart::ValueError | If maxLagSeconds is negative |
| hart::SampleRateError | If sample rates differ |
| hart::IndexError | If requested channel indices are out of range |
| hart::UnitError | If unsupported unit is requested |
Definition at line 99 of file hart_lag_at_max_cross_correlation.hpp.
|
inline |
Calculates difference between two spectra in log-frequency domain.
Definition at line 24 of file hart_log_spectral_distance.hpp.
|
inline |
Returns the center frequency of the loudest FFT bin.
Finds the maximum-magnitude FFT bin independently for each channel. Use reducers to combine multi-channel results (see Reducers).
Supports Unit::Hz (native/default) unit, so requesting a unit explicitly via MetricQuery::as() is not required.
This metric operates on FFT bins exactly as stored in the Spectrum. In a not-so-likely event where multiple bins have exactly the same magnitube, the lowest frequency will be returned. This is not intended for precise pitch tracking, but still useful for some types of tests, based around looking for peaks in a band of frequencies, but not a specific frequency.
For more precise peak frequency estimation, consider using Quinn's second estimator (hart::quinns2() metric) instead.
Usage examples:
| spectrum | Input frequency-domain spectrum |
| hart::UnitError | if unsupported unit is requested |
Definition at line 58 of file hart_loudest_bin_frequency.hpp.
|
inline |
Calculates the magnitude of the loudest FFT bin.
Finds the maximum-magnitude FFT bin independently for each channel. Use reducers to combine multi-channel results (see Reducers).
Supports:
Unit::linear (native/default)Unit::dB as linear ratio, not powerThis metric operates on FFT bins exactly as stored in the Spectrum.
Typical use cases:
Usage examples:
| spectrum | Input frequency-domain spectrum |
| hart::UnitError | if unsupported unit is requested |
Definition at line 60 of file hart_loudest_bin_magnitude.hpp.
| MetricQuery< double > maxCrossCorrelation | ( | const AudioBuffer< SampleType > & | bufferA, |
| const AudioBuffer< SampleType > & | bufferB, | ||
| double | maxLagSeconds, | ||
| CorrelationSearchMode | searchMode = bestAbsoluteCorrelation |
||
| ) |
Calculates maximum normalized cross-correlation between two audio buffers.
Searches for the best normalized cross-correlation value within a specified lag range independently for each selected pair of channels.
Cross-correlation is calculated using the following formula:
\[ \frac{\sum_n x[n]\,y[n+k]} {\sqrt{ \left(\sum_n x[n]^2\right) \left(\sum_n y[n+k]^2\right) }} \]
(sum (x[n] * y[n + k]) / sqrt (sum (x[n]^2) * sum (y[n + k]^2)))
where:
x[n] is the left-hand-side signaly[n + k] is the right-hand-side signal shifted by lag kk is searched in the range [-maxLag, +maxLag]The result is normalized to the range [-1, 1], where:
+1 means perfect positive correlation-1 means perfect negative correlation (polarity inversion)0 means no linear correlationDepending on searchMode, the metric either:
Correlation is calculated independently for each selected pair of channels. Use a reducer to combine multiple channel-pair results into a scalar.
Usage examples:
Notes:
bestAbsoluteCorrelation mode.NaN.Supports only Unit::native and Unit::none units.
| bufferA | Left-hand-side audio buffer |
| bufferB | Right-hand-side audio buffer |
| maxLagSeconds | Maximum lag to search in seconds |
| searchMode | Controls how the best lag is selected, see `CorrelationSearchMode` |
| SampleType | Floating point sample type, typically float or double |
| hart::ValueError | If maxLagSeconds is negative |
| hart::SampleRateError | If sample rates differ |
| hart::IndexError | If requested channel indices are out of range |
| hart::UnitError | If unsupported unit is requested |
Definition at line 109 of file hart_max_cross_correlation.hpp.
|
inline |
Returns somewhat accurate loudest frequency in the spectrum.
Implements algorithm commonly referred to as "Quinn's Second Estimator", described by B. G. Quinn in "Estimating frequency by interpolation using Fourier coefficients", IEEE Transactions on Signal Processing, Vol. 42, No. 5, pp. 1264-1268.
It's provides a quite accurate way if interpolating frequency value, that is somewhere in between FFT bin centers. Note that it's undefined near DC and Nyquist frequencies, and it will return NaN for those bins. For those edge cases, consider using a more simple hart::loudestBinFrequency() metric instead.
Supports Unit::Hz (native/default) unit, so requesting a unit explicitly via MetricQuery::as() is not required.
This metric operates on FFT bins exactly as stored in the Spectrum. In a not-so-likely event where multiple bins have exactly the same magnitube, the lowest frequency will be returned.
Usage examples:
| spectrum | Input frequency-domain spectrum |
| hart::UnitError | if unsupported unit is requested |
Definition at line 61 of file hart_quinns2.hpp.
| MetricQuery< double > rms | ( | const AudioBuffer< SampleType > & | buffer | ) |
Calculates root mean square (RMS) of a signal.
RMS a metric that expresses the average magnitude, or effective energy level, of an audio signal over time. It is commonly used to estimate perceived loudness, and to measure overall signal level.
RMS is calculated this way:
\[ \mathrm{RMS} = \sqrt{\frac{1}{N} \sum_{n=0}^{N-1} x[n]^2} \]
(RMS = sqrt((1 / N) * sum(x[n] ** 2))),
where x[n] is audio sample value from one channel, and N is number of frames in the provided buffer.
Can be expressed as ratio or decibels, supports Unit:native, Unit::linear, Unit::dB units. Value in decibels is calculated as a ratio, not power.
| SampleType |
| buffer | Audio buffer to calculate RMS at |
MetricQuery object, which calculates RMS as linear ratio or decibels Definition at line 41 of file hart_rms.hpp.
| MetricQuery< double > rt60 | ( | const ImpulseResponse< SampleType > & | ir, |
| RT60::Method | method = RT60::Method::edt |
||
| ) |
Estimates the RT60 reverberation time of an impulse response.
RT60 is the time required for reverberant energy to decay by 60 dB. The metric is calculated from the impulse response using Schroeder backward integration, followed by linear regression over the range specified by method. The fitted decay slope is then extrapolated to 60 dB.
EDT, T20 and T30, specified by method, are different estimators of the same RT60 quantity. For an exponential decay they're expected to produce identical results; for more complex decay curves you can use combination of those.
Supported units are Unit::seconds, Unit::native (same as seconds) and Unit::frames. If Unit::frames is requested, the result will be a fractional value.
This metric is based on ISO 3382 standard.
NaN. Also, note that DSPs that produce no decay or ringing at all (e. g., a system that just applies linear gain, or a stateless waveshaper) will result in NaN, and not zero.Also, make sure that provided IR is long enough to contain a portion of slope specified by method, otherwise the estimation will result NaN. See RT60::Method options documentation for details, and ISO 3382 for a more in-depth description.
| SampleType | Floating-point sample type of the impulse response. |
NaN.Definition at line 87 of file hart_rt60.hpp.
| MetricQuery< double > samplePeak | ( | const AudioBuffer< SampleType > & | audioBuffer | ) |
Calculates Sample Peak of an audio buffer.
Calculates rectified peak values for each channel. Use a reducer to get a scalar value (see Reducers). Supports Unit::linear (default) and Unit::dB units. Usage example:
truePeak() metric or TruePeaksBelow matcher. | audioBuffer | Buffer to measure sample peaks in. |
| hart::IndexError | if slice's boundary is out of audio buffer's range |
| hart::UnitError | if unsupported unit is requested |
Definition at line 33 of file hart_sample_peak.hpp.
| MetricQuery< double > snr | ( | const AudioBuffer< SampleType > & | signalPlusNoise, |
| const AudioBuffer< SampleType > & | signal | ||
| ) |
Calculates signal-to-noise ratio (SNR)
SNR expresses the ratio between the energy of a reference signal and the energy of the error, or noise, present in an estimated signal.
The noise component is calculated as the sample-by-sample difference between the estimated and reference signals.
SNR is calculated this way:
\[ \mathrm{SNR} = \frac {\sum_{n=0}^{N-1} r[n]^2} {\sum_{n=0}^{N-1} \left(x[n] - r[n]\right)^2} \]
(SNR = sum(r[n] ** 2) / sum((x[n] - r[n]) ** 2)),
where x[n] is a sample from the estimated signal, r[n] is the corresponding sample from the reference signal, and N is the number of frames being analyzed.
Higher values indicate a closer match to the reference signal, and thus lower noise. Identical signals produce positive infinity, and this metric will return +inf in those cases.
Can be expressed as an energy ratio or decibels. Supports Unit::ratio, Unit::native (same as ratio), and Unit::dB. Values in decibels are calculated as a power ratio:
\[ \mathrm{SNR_{dB}} = 10 \log_{10}\left(\mathrm{SNR}\right) \]
(SNR_dB = 10 * log10(SNR)).
The two buffers are expected to represent aligned versions of the same signal. Differences in gain, latency, phase, or other deterministic signal properties are included in the measured noise/error.
| SampleType |
| signalPlusNoise | Estimated or measured signal |
| signal | Reference signal to compare against |
MetricQuery object which calculates SNR as a linear energy ratio or in decibels. May return NaN or +inf. Definition at line 64 of file hart_snr.hpp.
| 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)
SNRa estimates the amount of aliasing introduced by an audio processing algorithm by comparing its output at the native sample rate against a higher-sample-rate render.
SNRa is particularly suitable for non-linear DSP such as waveshapers, saturation, clipping, nonlinear filters, limiters, nonlinear circuit models, and anti-aliased waveform generators. It may be unsuitable for algorithms whose behavior changes materially with sample rate, such as fixed-rate processing engines or some fixed-size STFT-based algorithms.
This metric implies a specific experiment:
AudioBuffer's to this metric. They're expected to have matching lengths in seconds, but different sample rates - all resampling will be done by this metric internally.You may pick the exact high sample rate value yourself. This sample rate doesn't have to be an integer multiple o the "native" sample rate, although typically you might still use something like 4x or 8x of native sample rate. Obviously, the higher the better.
Keep in mind that "high sample rate" refers to a "host" sample rate, and doesn't take into account any internal oversampling your DSP testee might have. If your DSP has internal oversampling, keep it on in both renders at the same setting. So, if your DSP has internal 4x OS, and native SR is 44.1 kHz, you keep internal oversampling on, and do a first render at 44.1 kHz, and then a second render at, say, 196 kHz (which, assuming your DSP does 4x OS internally, will result in a whopping 784 kHz internally, but HART renders everuthing offline, so you don't have to worry about potential non-realtime performance here).
The reference (high SR) buffer is internally resampled to the native sample rate. Aliasing noise is then defined as the sample-by-sample difference betweenthe native-rate output and this resampled reference.
SNRa is calculated as:
\[ \mathrm{SNR_a} = \frac {\sum_{n=0}^{N-1} r[n]^2} {\sum_{n=0}^{N-1} \left(x[n] - r[n]\right)^2} \]
(SNRa = sum(r[n] ** 2) / sum((x[n] - r[n]) ** 2)),
where x[n] is a sample from the output rendered at the native sample rate, r[n] is the corresponding sample from the higher-sample-rate reference after it has been resampled to the native sample rate, and N is the number of frames being analyzed.
Higher values indicate less aliasing, so higher is better. A perfectly matching native-rate and reference signal produces positive infinity, and this metric will return +inf.
Can be requested as an energy ratio or decibels. Supports Unit::ratio, Unit::native (default, same as Unit::ratio), and Unit::dB. Values in decibels are calculated as a power ratio:
\[ \mathrm{SNR_{a}},dB = 10 \log_{10}\left(\mathrm{SNR_a}\right) \]
(SNRa_dB = 10 * log10(SNRa)).
As mentioned above, this metric assumes that the two buffers are equivalent renders of the same algorithm and state, with the reference buffer rendered at a higher sample rate. In particular:
The reference audio resampling operation may introduce boundary transients at the beginning and end of the buffer. For accurate measurements, render guard regions around the desired analysis interval, and use MetricQuery::at() with an appropriate hart::Slice to measure only an interior, settled slice of audio.
See tests/test_metrics.cpp, in particular the "Metrics - SNRa - Distortion effect with aliasing" and "Metrics - SNRa - Clean effect with no aliasing" tests, for complete experiment examples.
| SampleType | Type of audio buffers' values, typically float or double |
| estimatedBufferAtNativeSR | Output rendered at the native sample rate. This will be considered to be a "signal + aliasing noise" when estimating SNRa. |
| referenceBufferAtHighSR | Equivalent reference output rendered at a higher sample rate. This audio buffer will be considered to be an ideal signal with no aliasing ("signal") when estimating SNRa. This signal should be captured at a higher sample rate that estimatedBufferAtNativeSR, and will be internally resampled. Also, note that "high sample rate" refers to a "host" sample rate, and doesn't take into account any internal oversampling your DSP testee might have. |
MetricQuery object which calculates SNRa as a linear energy ratio or in decibels. May return NaN or +inf. Definition at line 133 of file hart_snra.hpp.
|
inline |
Calculates spectral centroid.
Commonly used to numerically express amound of "brightness" of a sound.
You have an option to pick one of two common weighting methods:
\[ C_{mag}=\frac{\sum_{k=0}^{N-1} f_k |X_k|}{\sum_{k=0}^{N-1} |X_k|} \]
(C_mag = sum(f_k * abs(X_k)) / sum(abs(X_k))),
\[ C_{pow}=\frac{\sum_{k=0}^{N-1} f_k |X_k|^2}{\sum_{k=0}^{N-1} |X_k|^2} \]
C_pow = sum(f_k * abs(X_k)^2) / sum(abs(X_k)^2)
Where fk is a center frequency of each bin, and Xk is a magnitude of this bin. In both cases the result is measured in Hertz, so accepted units are Unit::native and Unit::Hz, which are the same.
See Using Metrics And Reducers for how to use metrics that return a MetricQuery object line this one.
| spectrum | Spectrum of a single to operate on |
| weighting | Type of weighting (see description above) |
MetricQuery, which calculates per-channel spectral centroid values in Hz Definition at line 55 of file hart_spectral_centroid.hpp.
|
inline |
Calculates spectral flatness, also known as Wiener entropy, or tonality coefficient.
Useful to judge how noise-like spectrum is.
You have an option to pick one of two common weighting methods:
\[ \mathrm{SpectralFlatness} = \frac{ \exp \left( \frac{1}{N} \sum_{n=0}^{N-1} \ln(x[n]) \right) }{ \frac{1}{N} \sum_{n=0}^{N-1} x[n] } \]
(SpectralFlatness = exp(sum (log (x[n])) / N) / (sum(x[n]) / N),
Where x[n] is a magnitude of a bin, and N is number of bins. The result can be represented in Unit::linear (default/ native) or Unit::dB. For decibel value, it will be converted as power (not voltage).
Typical values:
See Using Metrics And Reducers for how to use metrics like this one.
| spectrum | Spectrum of a single to operate on |
| floorLinear | Bin magnitude threshold for numerical stability. Each bin's magnitude will be evaluated as x[n] = max (binMagnitudes[n], floorLinear). |
MetricQuery, which calculates per-channel spectral flatness values Definition at line 53 of file hart_spectral_flatness.hpp.
|
inline |
Calculates slope of the spectrum in logX-logY domain.
Definition at line 24 of file hart_spectral_log_log_slope.hpp.
|
inline |
Calculates the total harmonic distortion (THD) of a spectrum.
THD is calculated as the square root of the summed harmonic power divided by the fundamental bin power:
\[ \mathrm{THD} = \sqrt{ \frac{\sum_{h=2}^{H} |X[h k_1]|^2} {|X[k_1]|^2} } \]
(THD = sqrt(sum(norm(harmonic bins)) / norm(fundamental bin))),
where \( k_1 \) is the FFT bin containing the fundamental, and \( H \) is the maximum harmonic number requested. Harmonics at or above the Nyquist frequency are ignored.
For an accurate measurement, the input should be a pure sine whose frequency lies exactly at the centre of an FFT bin. The analysed signal should also contain exactly the same number of frames as the FFT, without zero padding. Otherwise, truncation and zero padding cause spectral leakage, which may appear as harmonic energy and artificially increase the measured THD.
To ensure those conditions are met, you're expected to obtain a "tuned" experiment setup, obtained through hart::THD::ExperimentSetupTuner, which will snap all of your desired experiment parameters to the values optimized for no-spill FFT. Those will be the values you're supposed to run the entire test render with.
Example:
Supported units:
hart::Unit::ratio - as a ratiohart::Unit::native - default unit, same as ratiohart::Unit::dB - as decibels, using a "ratio" (not "power") variety of decibelshart::Unit::percent - as percentage - just ratio multipled by 100, may be fractional| spectrum | Spectrum of the output signal to analyse, assuming the input was a pure sine wave |
| experimentSetup | Optimized experiment setup values obtained through hart::THD::ExperimentSetupTuner(). |
NaN. Definition at line 428 of file hart_thd.hpp.
| MetricQuery< double > truePeak | ( | const AudioBuffer< SampleType > & | audioBuffer, |
| Oversampling | oversamplingRatio = Oversampling::x4, |
||
| typename TruePeak< SampleType >::FilterQuality | filterQuality = TruePeak<SampleType>::FilterQuality::low |
||
| ) |
Estimates true peak (inter-sample peak) level.
It checks inter-sample peaks by observing oversampled signal, following ITU-R BS.1770-5 guidelines. Some of the implementation choices are exposed via arguments, such as oversampling factor and number of taps in the internal poly-phase FIR filter, as the standard does not specify the exact values.
Supports values in dB TP (Unit::dB) and linear domain (Unit::linear). Operating at default unit (Unit::native) will yield values in dB TP.
Shares the same implementation as TruePeaksBelow matcher, but lets you make more versatile expressions.
| audioBuffer | Buffer to estimate true peaks in |
| oversamplingRatio | Oversampling for the estimator. Higher OS ratios are expected to result in more accurate estimations. |
| filterQuality | Represent number of taps for the internal FIR filter. Higher will result in more accurate estimate. Note that even the highest filter quality is way lower than what is used in actual DAC oversamplers, but it's okay, since we're merely estimating here. |
Definition at line 265 of file hart_true_peak.hpp.
| MetricQuery< double > zcr | ( | const AudioBuffer< SampleType > & | buffer | ) |
Calculates zero-crossing rate (ZCR) of a signal.
Useful to estimate frequency of stationary monophonic signals. Supports Unit::native and Unit::Hz units, which both result in the same value.
| SampleType | type of audio buffer data, typically float or double |
| buffer | Audio buffer to calculate ZCR at |
MetricQuery object, which calculates RMS as linear ratio or decibels Definition at line 23 of file hart_zcr.hpp.