Three-way classification of an oscillator's output into harmonic / alias / noise, with the worst in-band alias called out. More...
#include <audio_spectrum.hpp>
Public Attributes | |
| std::string | analyzer = "alias" |
| double | fundamental_hz = 0.0 |
| double | sample_rate = 0.0 |
| double | nyquist_hz = 0.0 |
| double | max_alias_frequency_hz = 0.0 |
| The band qualifier that was used. | |
| int | num_harmonics = 0 |
| int | analysis_offset = 0 |
| int | analysis_length = 0 |
| Samples actually fitted. | |
| double | bin_hz = 0.0 |
| Fit resolution: sample_rate / analysis_length. | |
| double | fundamental_amplitude = 0.0 |
| Fitted amplitude of the fundamental — the reference every dB below is relative to. | |
| std::vector< AliasComponent > | components |
| Every expected component h = 1..num_harmonics, in order, each labeled harmonic or alias by where h · f0 fell relative to Nyquist. | |
| double | worst_alias_db = kSilenceFloorDb |
| Worst (loudest) alias landing at or below max_alias_frequency_hz, in dB relative to the fundamental. | |
| double | worst_alias_hz = 0.0 |
| Where it landed. | |
| int | worst_alias_index = 0 |
| Which h produced it (0 = none). | |
| double | full_band_worst_alias_db = kSilenceFloorDb |
| The unqualified worst alias at ANY frequency up to Nyquist. | |
| double | full_band_worst_alias_hz = 0.0 |
| double | noise_db = kSilenceFloorDb |
| Everything the fit could not attribute to any expected component: RMS of the residual, in dB relative to the fundamental's RMS. | |
| double | detection_floor_db = kSilenceFloorDb |
| The quietest single component this measurement could have detected, in dB relative to the fundamental — a ≈2σ statistical bound derived from the residual and the fit length, ASSUMING the residual is white. | |
| bool | has_unresolved_in_band_alias = false |
| True when at least one ALIAS inside the band could not be resolved. | |
Three-way classification of an oscillator's output into harmonic / alias / noise, with the worst in-band alias called out.
The method is projection, not bin classification: the full set of expected landing sites (in-band harmonics AND the fold-back sites of every harmonic above Nyquist) is fitted JOINTLY by least squares, and whatever is left over is noise. Fitting jointly rather than site-by-site buys exactness at the resolution limit and — more importantly — a solve that collapses audibly when two sites genuinely cannot be separated, which is what resolved and has_unresolved_in_band_alias report.
Determinism contract: pure arithmetic over the supplied buffer — no window, no FFT, no power-of-two length, no coherence requirement, and no dependence on where analysis_offset starts. Amplitudes are in input units and every dB is a ratio, so nothing here depends on an FFT backend's normalization.
| int pulp::test::audio::AliasReport::analysis_length = 0 |
Samples actually fitted.
| int pulp::test::audio::AliasReport::analysis_offset = 0 |
| std::string pulp::test::audio::AliasReport::analyzer = "alias" |
| double pulp::test::audio::AliasReport::bin_hz = 0.0 |
Fit resolution: sample_rate / analysis_length.
| std::vector<AliasComponent> pulp::test::audio::AliasReport::components |
Every expected component h = 1..num_harmonics, in order, each labeled harmonic or alias by where h · f0 fell relative to Nyquist.
| double pulp::test::audio::AliasReport::detection_floor_db = kSilenceFloorDb |
The quietest single component this measurement could have detected, in dB relative to the fundamental — a ≈2σ statistical bound derived from the residual and the fit length, ASSUMING the residual is white.
Never assert a gate on this number. That would be the analyzer grading its own homework, and the white-residual assumption fails exactly when it matters: an unmodeled alias is a discrete TONE, and a tone-dominated residual makes this bound optimistic (noise_db sitting near worst_alias_db is the tell). The floor a gate leans on must be PROVEN by negative control instead — a fixture with zero alias content by construction must read collapsed, and injected components of known level must be recovered. test_audio_doctor.cpp's clean-series and injected-alias tests are the pattern.
Its one legitimate use is the inconclusiveness check: a gate is trustworthy only while worst_alias_db clears this floor. When it does not, the measurement could not distinguish its own residual from a component and the report is INCONCLUSIVE — fail closed rather than reading it as a pass.
| double pulp::test::audio::AliasReport::full_band_worst_alias_db = kSilenceFloorDb |
The unqualified worst alias at ANY frequency up to Nyquist.
Reported for characterization and honesty — do NOT gate on it (see AliasOptions::max_alias_frequency_hz for why no implementation can pass such a gate).
| double pulp::test::audio::AliasReport::full_band_worst_alias_hz = 0.0 |
| double pulp::test::audio::AliasReport::fundamental_amplitude = 0.0 |
Fitted amplitude of the fundamental — the reference every dB below is relative to.
| double pulp::test::audio::AliasReport::fundamental_hz = 0.0 |
| bool pulp::test::audio::AliasReport::has_unresolved_in_band_alias = false |
True when at least one ALIAS inside the band could not be resolved.
A gate must fail closed (or report inconclusive) on this — worst_alias_db silently omits those components.
| double pulp::test::audio::AliasReport::max_alias_frequency_hz = 0.0 |
The band qualifier that was used.
| double pulp::test::audio::AliasReport::noise_db = kSilenceFloorDb |
Everything the fit could not attribute to any expected component: RMS of the residual, in dB relative to the fundamental's RMS.
Broadband noise, intermodulation, and any alias from a harmonic beyond num_harmonics all land here.
| int pulp::test::audio::AliasReport::num_harmonics = 0 |
| double pulp::test::audio::AliasReport::nyquist_hz = 0.0 |
| double pulp::test::audio::AliasReport::sample_rate = 0.0 |
| double pulp::test::audio::AliasReport::worst_alias_db = kSilenceFloorDb |
Worst (loudest) alias landing at or below max_alias_frequency_hz, in dB relative to the fundamental.
This is the number to gate on. kSilenceFloorDb when the series produces no resolved in-band alias.
| double pulp::test::audio::AliasReport::worst_alias_hz = 0.0 |
Where it landed.
| int pulp::test::audio::AliasReport::worst_alias_index = 0 |
Which h produced it (0 = none).