HART  0.2.0
High level Audio Regression and Testing
Loading...
Searching...
No Matches
ExperimentSetupTuner Class Reference

Configures and tunes an experiment setup for accurate THD measurement. More...

#include <hart_thd.hpp>

Public Member Functions

ExperimentSetupTunerwithFrequency (double desiredFrequencyHz)
 Sets the desired frequency of the input signal.
 
ExperimentSetupTunerwithSampleRate (double sampleRateHz)
 Sample rate of the test case.
 
ExperimentSetupTunerwithDuration (double desiredDurationSeconds)
 Sets desired render time of the test case in seconds.
 
ExperimentSetupTunerwithNumFrames (size_t desiredDurationFrames)
 Sets desired render time of the test case in frames.
 
ExperimentSetupTunerwithMaxHarmonic (int desiredMaxHarmonic)
 Sets desired number of harmonics for the THD measurement.
 
ExperimentSetup tune () const
 Call it at the end of the builder chain to produce a hart::THD::ExperimentSetup instance.
 

Detailed Description

Configures and tunes an experiment setup for accurate THD measurement.

Intended to be used for hart::thd() metric.

THD measurement requires a pure sine, whose fundamental frequency should fall exactly on an FFT bin. The analysed signal should also contain exactly the same number of frames as the FFT, without zero padding. Otherwise, spectral leakage may appear as harmonic energy and artificially increase the measured THD.

This class takes the desired experiment parameters and tunes them to satisfy these requirements for you. The tune() method:

  • Snaps the requested duration to a number of frames that is a power of two
  • Snaps the requested fundamental frequency to centre of the nearest valid FFT bin
  • Limits the number of harmonics to those measurable below Nyquist frequency bin

Examples:

// 1. Tune the desired experiment parameters
.withFrequency (1000_Hz)
.withSampleRate (44100_Hz)
.withDuration (100_ms) // or withNumFrames(n)
.tune();
// 2. Run the experiment (render the audio), using the tuned values...
processAudioWith (SomeDSP())
.withInputSignal (SineWave (setup.frequencyHz)) // ...here...
.withDuration (setup.durationSeconds) // ...and here.
.expectTrue (
[setup] (const auto& output)
{
return HART_EXPECT_LT (
// 3. Call the thd() metric, passing the same setup structure to it
hart::thd (hart::Spectrum (output), setup).get(),
0.01);
},
"THD < 0.1"
)
.process();
Produces a sine wave at fixed frequency.
Frequency-domain representation of a multi-channel audio signal.
Configures and tunes an experiment setup for accurate THD measurement.
Definition hart_thd.hpp:162
ExperimentSetupTuner & withDuration(double desiredDurationSeconds)
Sets desired render time of the test case in seconds.
Definition hart_thd.hpp:204
ExperimentSetupTuner & withMaxHarmonic(int desiredMaxHarmonic)
Sets desired number of harmonics for the THD measurement.
Definition hart_thd.hpp:242
ExperimentSetupTuner & withSampleRate(double sampleRateHz)
Sample rate of the test case.
Definition hart_thd.hpp:183
ExperimentSetupTuner & withFrequency(double desiredFrequencyHz)
Sets the desired frequency of the input signal.
Definition hart_thd.hpp:170
ExperimentSetup tune() const
Call it at the end of the builder chain to produce a hart::THD::ExperimentSetup instance.
Definition hart_thd.hpp:261
#define HART_EXPECT_LT(lhs, rhs)
MetricQuery< double > thd(const Spectrum &spectrum, THD::ExperimentSetup experimentSetup)
Calculates the total harmonic distortion (THD) of a spectrum.
Definition hart_thd.hpp:428
AudioTestBuilder< typename std::decay< DSPType >::type::SampleTypePublicAlias > processAudioWith(DSPType &&dsp)
Call this to start building your test using a DSP object.
A tuned setup for optimal THD measurement.
Definition hart_thd.hpp:30
const double durationSeconds
Optimized duration of audio for FFT with no padding.
Definition hart_thd.hpp:42
const double frequencyHz
Optimized frequency of the input sine wave.
Definition hart_thd.hpp:34

If the desired duration is already expressed in frames, withNumFrames() can be used instead:

.withFrequency (1000_Hz)
.withNumFrames (4096)
.tune();
// (Then run the test)
ExperimentSetupTuner & withNumFrames(size_t desiredDurationFrames)
Sets desired render time of the test case in frames.
Definition hart_thd.hpp:226

The most minimal scenario can look like this:

const auto setup = hart::THD::ExperimentSetupTuner()
.withFrequency (1000_Hz)
.tune();
// (Then run the test)

In that case, the duration and sample rate will be pulled from hart::CLIConfig, and be the same as the defaults in the usual hart::AudioTestBuilder.

Definition at line 161 of file hart_thd.hpp.

Member Function Documentation

◆ withFrequency()

ExperimentSetupTuner & withFrequency ( double  desiredFrequencyHz)
inline

Sets the desired frequency of the input signal.

It will be tuned to fall exactly in the centre of an FFT bin.

If omitted, this desired frequency will be assumed to be 1 kHz.

Parameters
desiredFrequencyHzYour desired frequency of a sine wave in the input signal
Returns
A chainable builder

Definition at line 170 of file hart_thd.hpp.

◆ withSampleRate()

ExperimentSetupTuner & withSampleRate ( double  sampleRateHz)
inline

Sample rate of the test case.

If omitted, the global default sample rate will be pulled from hart::CLIConfig

Parameters
sampleRateHzSample rate in Herts
Returns
A chainable builder

Definition at line 183 of file hart_thd.hpp.

◆ withDuration()

ExperimentSetupTuner & withDuration ( double  desiredDurationSeconds)
inline

Sets desired render time of the test case in seconds.

Alternatively, you can set this duration in frames, using withNumFrames(). There's no need to call both seconds and frames setters in one chained builder, use no more than one - either this one, or withNumFrames().

If both seconds and frames setters are omitted, the global default duration will be pulled from hart::CLIConfig.

This value be tuned in a way that resulting rendered audio will have number of frames that is a power of two, so that no FFT zero padding would be required.

Parameters
desiredDurationSecondsDesired render time in seconds
Returns
A chainable builder

Definition at line 204 of file hart_thd.hpp.

◆ withNumFrames()

ExperimentSetupTuner & withNumFrames ( size_t  desiredDurationFrames)
inline

Sets desired render time of the test case in frames.

Alternatively, you can set this duration in seconds, using withDuration(). There's no need to call both seconds and frames setters in one chained builder, use no more than one - either this one, or withDuration().

If both seconds and frames setters are omitted, the global default duration will be pulled from hart::CLIConfig.

This value be tuned in a way that resulting rendered audio will have number of frames that is a power of two, so that no FFT zero padding would be required.

Parameters
desiredDurationFramesDesired size of rendered audio in frames
Returns
A chainable builder

Definition at line 226 of file hart_thd.hpp.

◆ withMaxHarmonic()

ExperimentSetupTuner & withMaxHarmonic ( int  desiredMaxHarmonic)
inline

Sets desired number of harmonics for the THD measurement.

This value will be limited in a way it's always under the Nyquist bin in the resulting FFT.

Parameters
desiredMaxHarmonicDesired highest harmonic used for the THD calculation (fundamental is number 1)
Returns

Definition at line 242 of file hart_thd.hpp.

◆ tune()

ExperimentSetup tune ( ) const
inline

Call it at the end of the builder chain to produce a hart::THD::ExperimentSetup instance.

This will give you a structure with tunes experiment setup values inside.

You're expected to use those values for the test case, namely sine wave frequency and render duration, instead of your desired values used in this builder. The values will be different from the desired ones (except for rare lucky cases), but they'll be optimized for an accurate THD reading, with no FFT spills. You're also expected to pass the same instance of experiment setup to the hart::thd() metric, so that it has all experiment context it needs.

Returns
A hart::THD::ExperimentSetup instance containing tuned values for the THD measurement experiment.

Definition at line 261 of file hart_thd.hpp.


The documentation for this class was generated from the following file: