the analyser byte spectrum is the defined quantisation of its float spectrum
Check id audio-analyser-float-vs-byte
What an ordinary browser yields
Every finite bin within one of the byte value derived from its own decibel reading (severity: warn).
What a detector infers
An AnalyserNode publishes the same spectrum twice. getFloatFrequencyData returns decibels, and getByteFrequencyData returns that spectrum quantised by a conversion the specification fixes: byte equals 255 times the decibel value minus minDecibels, divided by the decibel range, rounded and clamped. The two are therefore not independent readings -- the second is a function of the first -- which makes this pure arithmetic on the browser own numbers, with no reference spectrum and no audio hardware involved. It cannot drift with a driver or an output device. Audio farbling usually perturbs the float path, because that is what fingerprinting scripts hash; doing so after the byte view has been derived, or perturbing only one of the two, breaks the conversion. Perturbing the underlying buffer before both leaves this row quiet, which is correct and is the same distinction the canvas dual-exit row draws. Measured on a clean browser, rendered through an OfflineAudioContext so nothing depends on an output device: 256 bins, 256 compared, zero mismatches, with minDecibels -100 and maxDecibels -30. A per-bin tolerance of one is allowed because the conversion rounds and a value on a boundary can land either side. The analyser's smoothingTimeConstant is pinned to 0 before the two reads: each getXFrequencyData call runs a fresh FFT with smoothing applied, so at the 0.8 default the second read is smoothed against the first and the two views diverge for a reason unrelated to tampering. Measured: Firefox at 0.8 reports 125 of 256 bins mismatching (worst 19), and 0 at smoothing 0 in either read order; Chromium reports 0 in every arm, which is why this only ever misfired on Gecko.
How to resolve it
getByteFrequencyData is a defined rescaling of the decibel values getFloatFrequencyData reports, using the analyser own minDecibels and maxDecibels, not a second measurement. Perturbing the float path after the byte view is derived, or perturbing only one of them, breaks arithmetic rather than hiding a fingerprint. Perturb the buffer before the analyser reads it so both views follow, or neither.
Nearby checks in Environment & locale
- navigator.plugins is a real platform object (structured-clone probe)
plugins-structured-cloneThe structured-clone algorithm is implemented in C++ and interrogates objects about what they actually are, not what they claim. - canPlayType answers identically for <video>, <audio> and the prototype
canplaytype-element-agnosticcanPlayType is implemented exactly once, on HTMLMediaElement.prototype, so <video> and <audio> inherit the same C++ function. - canPlayType behaves like a real codec parser (bogus + quoting)
canplaytype-parser-trapsA real canPlayType is an RFC-6381 parser, not a dictionary. This check exercises two properties only a parser has. - AudioContext invariants + a deterministic offline render
audio-context-coherenceThe check constructs a live AudioContext and reads four invariants — sampleRate, baseLatency, the destination node's channelCount against… - speech synthesis voices (host OS speech engine)
speech-voicesspeechSynthesis.getVoices() enumerates the host operating system's speech engine — a resource stealth stacks essentially never touch, which… - the voice list arrives the way Chrome delivers it
speech-voices-async-pathspeech-voices reads WHAT is in the voice list. This reads HOW the list arrived, which is a separate fact and survives a roster whose every… - an OS that ships a speech synthesiser enumerates at least one voice
speech-voices-vs-platformThe plain speech-voices readout above refuses to score an empty list, and as written it is right to: Chrome does not build the voice list in… - a live audio destination corresponds to an audio device that exists
audio-sink-vs-device-listA resource oracle, and deliberately a different resource from the voice list.
Clearcote is a browser built for fingerprint coherence
It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.
This audit takes no position on how Clearcote scores on Environment & locale checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.
See the other checks in Environment & locale — the family audio-analyser-float-vs-byte belongs to.