Overview
DecibelMeter is a browser-based sound level estimation tool. It uses the device microphone via the Web Audio API, computes sound levels locally in JavaScript, and displays real-time decibel values with optional A, C, and Z frequency weighting, Fast/Slow/Impulse time weighting, RMS and Peak modes, and Leq. No audio is uploaded; all processing stays on the device.
Browser Microphone Access & Digital Audio
When the user taps Start Measuring, the page requests microphone access via
navigator.mediaDevices.getUserMedia() with:
echoCancellation: falsenoiseSuppression: falseautoGainControl: falsechannelCount: 1
The request asks the browser and operating system not to alter the signal. Some devices honor this; others
apply processing regardless — the Device & Microphone Information panel shows what was actually applied.
The stream is fed into an AudioContext → MediaStreamSource → AnalyserNode graph.
The analyser provides a Float32Array of 2048 time-domain samples per frame and a frequency-domain
Float32Array of the same length via FFT.
The AudioContext.sampleRate is typically 48000 Hz or 44100 Hz, determined by the device. At 48 kHz,
a 2048-sample window represents ~42.7 ms of audio; the loop runs via requestAnimationFrame, yielding
roughly 60 updates per second. Each update reads the latest buffer without blocking the audio thread.
Sampling, RMS, and Why It Matters
Each frame contains samples x[i] ∈ [−1, 1], the instantaneous normalized amplitude reported by the browser. The tool computes the root-mean-square (RMS) over the buffer:
Peak = max |x[i]| over the same buffer.
Where N = 2048 (fftSize).
RMS is the effective continuous level of the signal and corresponds more closely to perceived loudness than
instantaneous peaks. Peak captures the single highest pressure instant in the window and is relevant for impulse
sounds (claps, impacts). In RMS mode the displayed level derives from RMS; in Peak mode
it derives from max(peak, 1.15·RMS) so brief transients react visibly (~8 dB higher for sharp impulses)
without flooding the display with noise-floor jitter.
From Amplitude to Decibels
The raw amplitude is converted to decibels-full-scale (dBFS) via:
dB SPL = clamp(0–130, dBFS + referenceOffset + userCalibrationOffset)
where
referenceOffset = 94 + 30 = 124 dB (estimator baseline) and userCalibrationOffset ∈ [-40,+40] dB (device-specific, default 0, local-only).
The 94 dB constant is the standard acoustic reference (1 Pa RMS at 1 kHz corresponds to 94 dB SPL).
The additional +30 dB estimator bias is an empirical population-average correction so that typical phone mics
at normal speech levels (~60 dB SPL) read plausibly before per-device calibration — without it many devices would show ~30 dB for the same source
(the previous 0 dB default vs a ~60 dB reference). This bias is part of the documented estimator baseline (referenceOffset = 124 dB for 0 dBFS), not a per-device calibration.
The per-device userCalibrationOffset (default 0, shown as “Uncalibrated estimate” until you calibrate, persistent per-browser in localStorage under dbm_cal_offset and dbm_is_calibrated, editable via the Calibrate dialog as offset = reference − reading) corrects your specific microphone’s sensitivity.
The result is clamped to 0–130 dB and guarded against NaN/Infinity.
Note: consumer microphones are not factory-calibrated SPL sensors. The conversion is mathematically defensible and consistent, but absolute accuracy depends on the hardware and is only meaningful after calibration against a trusted reference. Uncalibrated readings are estimates for reference and education, not suitable for legal, medical, occupational, or regulatory decisions. We do not claim that browser dBFS equals certified SPL without that step, and we do not label the browser approximation as standards-compliant.
Peak Measurement
Peak is the highest instantaneous dB SPL observed in any frame since the session started. It is updated as
peak = max(peak, currentFrameDbSPL) and shown as Peak dB in the statistics and export.
Because peak responds to sub-50 ms transients, compare it against Leq/average to distinguish impulse-dominated
environments (large peak–average gap) from steady noise (small gap).
Leq — Equivalent Continuous Sound Level
Leq is not the arithmetic mean of decibel numbers. It is the energy average over the entire session:
where Li is each frame's dB SPL and N is the frame count.
Internally the engine accumulates sumEnergy += 10^(Li/10) per frame and computes
Leq = 10·log10(sumEnergy / N). This correctly weights loud moments — a brief 100 dB burst raises Leq
far more than averaging 80, 80, 100 as (80+80+100)/3 = 86.7 would suggest. Leq equals the arithmetic mean only when
the level is perfectly steady. For exposure questions, always use Leq (whole-session energy) rather
than a single instant or the plain average.
Frequency Weighting: A, C, Z
The human ear is not flat — it is most sensitive around 2–5 kHz and rolls off at low and high frequencies. Frequency weighting applies a filter so the reading matches either perceived loudness or raw physics:
- A-weighting (dBA): attenuates lows/highs to mimic the ear at moderate levels; standard for environmental & occupational noise, NIOSH/OSHA limits, and all exposure guidance.
- C-weighting (dBC): much flatter; preserves bass; appropriate for loud, bass-heavy sound (music venues, engines, machinery); some peak limits are expressed in dBC.
- Z-weighting (dBZ): flat (zero) — no correction; the raw physical measurement across the audible band.
Implementation: the frequency-domain spectrum (from getFloatFrequencyData) is weighted bin-by-bin using
standard A and C transfer functions:
C(f): 20·log₁₀( 12194²·f² / ((f²+20.6²)(f²+12194²)) ) + 0.06
Linear gain = 10W/20 applied per FFT bin; total weighted power = Σ (mag·gain)²·Δf; weighted RMS = √(power / Nyquist).
The primary level uses the time-domain RMS (which avoids spectral leakage for narrowband signals) plus a bounded correction
delta = 20·log10(weightedRms / rawRms) clamped to [−10, +2] dB. In Z mode the correction is zero.
This keeps loud signals accurate while still reflecting the perceptual difference between weightings.
These are practical browser approximations using the standard A/C formulas per frequency bin — not certified IEC 61672 filter banks; we do not label the approximation as standards-compliant.
A, C, Z weighting curves (schematic)
Schematic only — not a metrology plot. A-weighting strongly attenuates lows and highs; C is much flatter; Z is flat. Curves plotted log-frequency vs. dB correction.
Time Weighting: Fast, Slow, Impulse
Time weighting controls how quickly the display reacts to level changes. It is implemented via the analyser's
smoothingTimeConstant and the frame averaging semantics:
- Fast (125 ms):
smoothing ≈ 0.2— close to IEC Fast; catches fluctuating noise; best for general use. - Slow (1 s):
smoothing ≈ 0.65— smooths short fluctuations; close to IEC Slow; best for steady levels. - Impulse (35 ms):
smoothing ≈ 0.08— very low smoothing so brief transients visibly spike; relevant for impacts/bangs.
These are practical browser approximations, not certified exponential detectors with 125 ms / 1 s exact time constants. For the energy aggregate (Leq), time weighting does not affect the result — Leq integrates raw frame levels directly.
Spectrum & Waveform Visualization
The waveform draws the time-domain buffer as a filled path (normalized amplitude vs. time). The
spectrum draws 64 frequency bands derived from the frequency-domain magnitudes
(getFloatFrequencyData, already in dBFS). The level visualization shows a calibrated
horizontal bar. All visualizations run on a dedicated requestAnimationFrame loop decoupled from the
audio computation so display work cannot starve the measurement.
Calibration Model
Calibration separates the estimator baseline from the device-specific adjustment:
userCalibrationOffset = referenceLevel − currentReading (range −40 … +40 dB, stored locally per browser/device, validated finite)
displayedLevel = clamp(0–130, dBFS + referenceOffset + userCalibrationOffset)
The referenceOffset is the internal estimator baseline needed to map browser amplitude (dBFS) to a plausible dB SPL for typical phones;
userCalibrationOffset is the per-device correction you set. Until you set it, the UI shows “Uncalibrated estimate” — the reading uses only the estimator baseline and is not suitable for legal, medical, occupational, or regulatory decisions.
Raw waveform and frequency-bin data are stored unmodified; the offset is applied only to derived dB values so all displayed statistics (current, min, max, avg, peak, Leq) stay consistent without corrupting the underlying signal.
The recommended workflow is to measure a steady source for 30–60 seconds, read the average / Leq
(not an instantaneous peak), enter the trusted reference level and the meter's current reading, and apply. Re-measure
the reference to verify agreement within ~1 dB. Calibration corrects sensitivity at the reference level; it
cannot correct frequency response, dynamic-range clipping, or pre-browser DSP. It persists only in localStorage (never on a server) under dbm_cal_offset / dbm_is_calibrated, validated to reject NaN/Infinity and bounded to ±40 dB with a clear error for impossible values; Reset calibration clears only the user adjustment and returns to the documented estimator baseline (user offset 0, “Uncalibrated estimate” shown).
Limitations & Honesty
- Consumer microphones vary unit-to-unit and are speech-optimized (boosted mids, rolled-off lows).
- Very quiet levels (<30 dB) may sit on the mic noise floor; very loud levels (>100 dB) may clip.
- Pre-browser DSP (AGC / noise suppression / echo cancellation) can remain active on some devices despite the request to disable it.
- Room reflections, distance (outdoors ≈ −6 dB per doubling of distance), orientation, and case covering the mic port all shift readings.
- Frequency-weighted corrections are approximate and bounded; they reflect perception well for broadband sounds but are not a replacement for a laboratory filter bank.
For regulatory, occupational, legal, or medical purposes use a certified Class 1 / Class 2 sound level meter (IEC 61672) calibrated by a laboratory. This tool is for useful estimates and education.
Signal Path Diagram
Microphone → browser audio capture (with requested DSP off) → Web Audio Analyser → RMS/Peak + frequency-weighted correction and time weighting → dB SPL conversion and calibration offset → display, statistics, history, and export.
Questions or corrections? Contact us — methodology text is reviewed against the live source code and updated when the implementation changes. See also Validation, Accuracy, and the Changelog.
src/lib/audio-engine.js). No third-party content is reproduced.