Fingerprinting · Browser Tests

Audio Fingerprint Test

Hash the output of your audio stack, a silent fingerprint that needs no microphone permission.

Rendering an audio graph…

Rendering the audio graph…

A silent tone is pushed through a compressor in an offline context, and the resulting samples are summed and hashed. No microphone is used.

The tone is rendered in memory and discarded. It is never routed to a speaker and this page never asks for microphone permission, so no permission prompt should appear for this test.

On this page
  1. What an audio fingerprint is
  2. How the graph is rendered
  3. No microphone, no prompt
  4. Why the value repeats
  5. How it stacks with other signals
  6. What it can identify
  7. What you can do about it

What an audio fingerprint is

An audio fingerprint is a value derived from the exact samples a browser produces when it renders a fixed sound. The page builds a small graph of audio nodes, asks the browser to render it into a buffer in memory, and sums the output. Because the Web Audio API delegates the maths to the platform’s audio libraries, that sum varies slightly from machine to machine, which makes it a usable identifier.

It is a strange signal, because nobody hears anything. There is no playback, no file to download and no recording of the room. The whole thing exists so the browser can be measured: the same graph is rendered on every visit, and any deviation in the output tells the page something about the machine it is running on.

Silent by construction

The waveform above is calculated, not played. The render destination is an offline buffer, so nothing is sent to your speakers or headphones.

How the audio graph is rendered

The graph is deliberately small and completely fixed. An OscillatorNode produces a triangle wave at 10000 Hz. It feeds a DynamicsCompressorNode with a threshold of -50 dB, a knee of 40 dB, a ratio of 12:1, an attack of 0 seconds and a release of 0.25 seconds. The compressor is there to shape the signal in a way that depends on real arithmetic rather than a simple lookup.

Rendering happens in an OfflineAudioContext with one channel and a sample rate of 44100 Hz, producing exactly 44100 samples for a one second render. It runs faster than real time because there is no clock to wait for. The widget then reads samples 4500 to 5000, a window of about 11 milliseconds, sums their absolute values and hashes the result.

Every difference between two machines comes from that arithmetic: how the platform audio library rounds floating-point operations, how the compressor’s curve is evaluated, and which CPU instructions the browser uses to do it.

No microphone, no permission

This is the part people find hardest to believe. Web Audio can capture from a microphone with getUserMedia, but that path requires an explicit permission grant and a visible browser prompt. Hashing an offline render needs neither, because nothing is being captured. The browser is generating a signal with code and measuring its own output.

That is what makes the technique appealing to trackers. It sits behind no prompt, no indicator and no consent dialog, so a visitor never sees it happen. If you are checking whether a site is using your microphone, this is not the test to watch; the media devices test lists which inputs and outputs your browser can even see, and navigator.permissions.query({ name: 'microphone' }) is the reliable way to read a microphone permission state.

Why the value repeats every time

The graph is deterministic, so the render is too. Run it a hundred times on the same machine and the sum comes back to the same floating-point digits, which the widget verifies by rendering three times and comparing. That reproducibility is what lets a site recognise a returning visitor: the value does not need to be unique across the world, only stable for you.

It does move, though. An operating system upgrade that replaces the audio stack, a browser update that changes its resampling code, or a switch between a 44.1 kHz and 48 kHz output device can all shift the value. The sample rate requested here is fixed at 44100 Hz so that device settings do not leak into the result, but the underlying library version still does. The canvas fingerprint behaves in much the same way for the same reason.

How it stacks with other signals

No single value decides who you are. The audio hash earns its place by agreeing with the others: a tracker that reads canvas, WebGL, fonts and audio together does not need any one of them to be unique, because the combination separates people far faster than a single column can.

The audio value is useful in that set for two reasons. It is cheap to collect, needing no prompt and no storage, and it is independent of the graphics stack, so it keeps splitting machines that a canvas or WebGL value has already grouped together. A laptop and a desktop sharing a GPU model and a browser build usually differ here, because their platform audio libraries are not the same code.

The browser fingerprint test shows the combined picture, while the canvas test and the WebGL test cover the signals this one sits beside.

What it can and cannot identify

The honest summary is that this is a strong consistency signal and a weak identity. It separates groups of machines reliably, and it is a good way to notice that the same browser has come back. It does not name a person, it does not read your files, and a site that stores only the hash cannot tell whether it belongs to one visitor or many.

Nor is it un-fakeable. Noise added to the rendered buffer, as some browsers do, changes the value without breaking audio playback, and a browser that simply refuses to expose the Web Audio API removes the signal altogether. Its real weight shows up in combination, which is exactly what the browser fingerprint test and the WebGL test measure alongside it.

What you can do about it

There is no switch labelled audio fingerprinting, and that is the first honest thing to say. What exists is a set of partial defences, each with a cost attached.

Brave adds small random noise to the rendered buffer, per site and per session, which leaves playback untouched but makes the hash differ every time. Firefox's fingerprinting protection can interfere with Web Audio in its stricter modes, and Tor Browser asks before a page may use the API at all. Each of these buys unlinkability rather than uniqueness, and each can break a site that genuinely plays or processes sound.

Frequently Asked Questions

Do I have to allow microphone access for this test?
No, and you should not see a prompt. The tone is generated in software with an oscillator and rendered into an offline buffer in memory. It is never captured from a device and never played through a speaker. The media devices test is the one that lists microphones and cameras, and even there nothing is recorded.
What is an audio fingerprint?
It is a number derived from the exact samples a browser produces when it renders a fixed audio graph. The Web Audio API hands the rendering to platform audio libraries, so tiny differences in floating-point rounding and signal processing show up in the output. The widget hashes that output, which turns it into a stable identifier.
Why would my audio hash differ from someone else’s?
The rendering path depends on your operating system’s audio stack, your CPU architecture and instruction set, and the browser build. Two people on the same browser can therefore produce slightly different sums. That variety is exactly what makes the signal useful to a tracker and useless as a way to name a specific person.
Can I block audio fingerprinting?
Harder than canvas. Brave adds per-session noise to the rendered buffer, which makes the value unstable across sites, and Firefox’s fingerprinting protection can interfere with the Web Audio API as well. Disabling Web Audio entirely is effective but breaks any site that plays sound, so it is rarely worth it. See the fingerprint test for the trade-off in context.
Is this value the same as my music or voice being recorded?
No. Nothing is captured. The graph is a single triangle wave at 10000 Hz pushed through a compressor, a synthetic signal with no connection to your voice, your files or anything playing on your machine. The whole point is that it is generated fresh, identically, on every visit so that the output can be compared.