👂 Psychoacoustic Masking
A loud tone raises the hearing threshold for nearby frequencies, hiding quieter sounds beneath a masking curve — the exact principle MP3 compression exploits to discard inaudible data.
How it Works
When a masker tone at frequency f_m and level L_m is played, it raises the effective hearing threshold in a region around f_m on the cochlea's frequency map. This region is best described on the Bark scale, which rescales frequency so that each unit (1 Bark) corresponds to roughly one critical bandwidth of the auditory filter bank. The raised threshold — the masking curve — is steep on the low-frequency side and much shallower on the high-frequency side, so low tones mask upward more effectively than high tones mask downward (the asymmetry of masking).
A probe tone at frequency f_p and level L_p is predicted audible only if L_p exceeds the masked threshold at f_p: whichever is higher of the normal quiet-hearing threshold, or the masker's spreading curve evaluated at the Bark distance Δz between f_p and f_m. This simulation implements a simplified piecewise-linear spreading function based on the model used in early MPEG perceptual audio coding — a useful, honestly-approximate stand-in for the true, smoothly curved auditory filter shape measured in psychoacoustic labs.
Quiet threshold (Terhardt 1979): T_q(f) = 3.64(f/1000)^-0.8 − 6.5·e^(−0.6(f/1000−3.3)²) + 0.001(f/1000)^4 dB SPL
Spreading fn SF(Δz,L_m), Δz = z(f_p) − z(f_m):
−3≤Δz<−1: 17Δz − 0.4L_m + 11
−1≤Δz<0: (0.4L_m+6)Δz
0≤Δz<1: −17Δz
1≤Δz≤8: (0.15L_m−17)Δz − 0.15L_m
Masked threshold: T_m(f_p) = max(T_q(f_p), L_m + SF(Δz,L_m))
Critical bandwidth (Zwicker 1961): CB(f) = 25 + 75·(1+1.4(f/1000)²)^0.69 Hz
Frequently Asked Questions
What is psychoacoustic masking?
Psychoacoustic masking is the phenomenon where a louder sound (the masker) raises the effective hearing threshold for other, quieter sounds (the probe) that fall near it in frequency and time. If the probe's level is below this raised threshold, it becomes inaudible even though it would be perfectly audible in silence.
Why is masking asymmetric — do low tones mask high tones more than the reverse?
Yes. The masking curve has a steep low-frequency skirt (roughly -27 dB per Bark below the masker) and a much shallower high-frequency skirt. This means a low-frequency masker spreads upward and masks higher frequencies more effectively than a high-frequency masker masks lower ones, a property called the asymmetry of masking or upward spread of masking.
How does MP3 and AAC compression exploit masking?
Perceptual audio codecs compute a masking threshold across the spectrum for every short block of audio, then allocate fewer quantization bits (or none at all) to frequency components that fall below that threshold, since a listener could not hear the added quantization noise there anyway. This lets the codec discard or coarsely encode inaudible information, shrinking file size with minimal perceived quality loss.
What is temporal masking (pre-masking and post-masking)?
Temporal masking is the time-domain counterpart of simultaneous masking. A loud sound can mask a softer sound that follows it for tens to hundreds of milliseconds (post-masking, or forward masking) and, more surprisingly, can even mask a softer sound that precedes it by a few milliseconds (pre-masking, or backward masking) because the auditory system needs time to process loud onsets. This simulation focuses on simultaneous (frequency-domain) masking only.
Why do critical bands and the Bark scale matter for masking?
The cochlea behaves like a bank of overlapping bandpass filters called critical bands; sounds within the same critical band interact and mask each other far more strongly than sounds in different bands. The Bark scale (24 bands spanning the audible range) rescales frequency so that each unit step corresponds to roughly one critical bandwidth, which is why masking curves are drawn and computed on a Bark axis rather than a linear Hz axis.
Why does raising the masker level widen the range of frequencies it masks?
The masking curve's height scales directly with masker level, and its high-frequency slope also becomes shallower as masker level increases, so a louder masker not only raises the threshold more but spreads that raised threshold across a wider frequency range, particularly upward in frequency.
Why might headphones reveal sounds that speakers hide, or vice versa?
Different playback systems and rooms alter the relative levels and spectral balance of simultaneous sounds. If a change in equipment shifts the level of a masker relative to a probe tone, a sound that sat below the masked threshold on one system can rise above it on another, making previously masked details suddenly audible.
Why does masking matter for hearing tests and audiology?
Clinical pure-tone audiometry must present a test tone to one ear while sometimes masking the other ear with noise, to prevent the non-test ear from "cross-hearing" the tone through bone conduction and giving a false threshold. Audiologists use calibrated masking noise levels derived from the same masking principles modeled in this simulation.
What is the spreading function used in this simulation?
This simulation uses a simplified piecewise-linear spreading function on the Bark scale, based on the classic model used in early MPEG perceptual audio coding (after Schroeder, Atal and Hall). It approximates the masking curve's shape with different slopes below and above the masker frequency, and is an approximation of the true auditory filter shape rather than an exact physiological measurement.
About this simulation
This simulator plots a masker tone's spreading curve on a Bark-scaled sound pressure level chart and checks whether a second, quieter probe tone rises above the resulting masked threshold. Drag the masker's frequency and level to reshape the curve, drag the probe to any frequency and level, then press Play to actually hear — through real Web Audio oscillators — whether the probe is buried under the masker or sits clearly above it.
🔬 What it shows
A live sound-pressure-level-versus-frequency plot combining the normal quiet-hearing threshold with a masker's asymmetric spreading curve, plus a probe-tone marker that turns green (audible) or red (masked) depending on whether its level clears maskedThresholdAt() at its own frequency.
🎮 How to use
Set the masker's frequency f_m and level L_m, then move the probe's frequency f_p and level L_p to probe the masking curve. Press Play tones to hear both together through Web Audio oscillators. P pauses the canvas animation, R resets all sliders.
💡 Did you know?
Because the masking curve's high-frequency skirt is far shallower than its low-frequency skirt, a bass-heavy masker can hide a much wider band of higher-pitched detail than a treble masker can hide bass — this asymmetry is one reason MP3 encoders spend extra bits protecting low frequencies.
Frequently asked questions
Why does moving f_p closer to f_m in Bark distance flip Status from Masked to Audible?
dz = bark(fp) − bark(fm) shrinks toward zero as f_p approaches f_m, and spreadingFunction(dz, Lm) is largest (least negative) near dz = 0, so maskedThresholdAt() climbs highest right around the masker — the probe has to clear that peak, which is why small Bark distances make masking strongest.
Why does raising L_m raise the masked threshold even at large frequency separations?
maskedThresholdAt() returns Math.max(quietThreshold(f), Lm + spreadingFunction(dz, Lm)), and the piecewise spreadingFunction() itself depends on Lm through terms like (0.4·Lm+6)·dz and (0.15·Lm−17)·dz, so a louder masker both starts from a higher Lm baseline and gets a shallower (less negative) slope, pushing the threshold up across a wider span of dz.
Why is the drawn masking curve steeper to the left of f_m than to the right?
The spreadingFunction() piecewise branches use very different slopes below zero (17·dz and (0.4Lm+6)·dz for negative dz, i.e. below the masker) versus above zero (−17·dz and (0.15Lm−17)·dz for positive dz), which directly encodes the real asymmetry-of-masking finding that the low-frequency skirt of the curve falls off far more steeply than the high-frequency skirt.
Why does criticalBandwidthHz() return a much larger number at 4000 Hz than at 200 Hz?
criticalBandwidthHz(f) implements Zwicker's 25 + 75·(1+1.4·(f/1000)²)^0.69 formula, whose (f/1000)² term grows quadratically, so critical bands widen sharply at higher center frequencies — this is why the Bark scale compresses high frequencies relative to Hz, packing many kHz into each Bark unit above a few kHz.
Why doesn't lowering L_p all the way to 0 dB ever make Status show anything but "Masked" near the masker?
maskedThresholdAt() always returns at least quietThreshold(f_p) even when the masker's spreading contribution is negative, so the Status can only read "Audible" once L_p climbs above whichever of the quiet threshold or the masker curve is higher — dropping L_p just makes the gap to that floor larger, not the floor itself lower.
A loud tone raises the hearing threshold for nearby frequencies, hiding quieter sounds beneath a masking curve — the exact principle MP3 compression exploits to discard inaudible data.
2D · HTML5 Canvas 2D · 60 FPS target · runs fully client-side, no install