Measurement methodology
This document explains how OnlineSoundMeter captures, processes, and displays sound level data. It's intended for users who want to understand what's happening technically - what the numbers mean, how they're derived, and where the limitations are.
Audio capture
We access your microphone through the browser's navigator.mediaDevices.getUserMedia() API. The audio constraints we request are specific and deliberate:
- echoCancellation: false - Echo cancellation removes room reflections, which would lower apparent volume readings.
- noiseSuppression: false - Noise suppression algorithms remove low-level ambient sound, the exact thing we're trying to measure.
- autoGainControl: false - AGC normalizes volume over time, making quiet sounds louder and loud sounds quieter. This destroys any meaningful dB reading.
These constraints matter because the default browser behavior is to enable all three - they're designed for voice calls, not measurement. With them active, a 40 dB room and a 65 dB room can produce nearly identical readings.
Signal processing
Once we have the audio stream, we connect it to the Web Audio API's AnalyserNode. This node performs the DSP work without sending audio anywhere - it operates entirely in the browser's audio thread.
Our configuration:
- FFT size: 2048 samples - This gives us 1024 frequency bins. Larger FFT means better frequency resolution but slower response time. 2048 is the standard balance for real-time display.
- Smoothing: 0.8 - Each frame blends 80% of the previous data with 20% new data. This prevents the display from flickering wildly while still responding to changes within ~200ms.
- Time-domain buffer: 2048 samples - We read the raw waveform for RMS calculation, sampled at the device's native rate.
- Sample rate: device-native - Typically 44,100 Hz or 48,000 Hz depending on hardware. We don't resample.
The AnalyserNode runs continuously via requestAnimationFrame, giving us approximately 60 readings per second on most devices.
dB calculation
The decibel reading is derived from the time-domain waveform data in three steps:
- Calculate RMS amplitude. We square each sample value, take the mean, then square root:
rms = sqrt(sum(sample²) / N). This gives us a single value representing the signal's effective amplitude. - Convert to decibels. Apply the standard formula:
dB = 20 * log10(rms). This converts the linear amplitude ratio to a logarithmic scale. - Add 90 dB offset. The raw calculation gives values from approximately -90 (silence) to 0 (full-scale digital). We add 90 to shift this into an approximate SPL range (0-90+), making the numbers intuitive: silence reads near 0, loud sounds read 80-100+.
Why +90? The Web Audio API normalizes audio samples to a -1.0 to 1.0 float range. Full-scale digital (1.0 RMS, which never happens with real audio) would be 0 dBFS. Real microphone signals sit far below this. The +90 offset approximates the mapping from digital full-scale to SPL, assuming a typical consumer microphone sensitivity. It's an approximation, not a calibration.
Final values are clamped to 0-120 dB and rounded to one decimal place.
Frequency analysis
The AnalyserNode's FFT provides frequency-domain data alongside the time-domain waveform:
- Bin resolution:
sampleRate / fftSize. At 48 kHz with 2048-point FFT, each bin spans ~23.4 Hz. At 44.1 kHz, ~21.5 Hz. - Frequency range: From ~20 Hz (we skip bins below this as they're dominated by DC offset and rumble) up to the Nyquist frequency (half the sample rate: 22,050 Hz or 24,000 Hz).
- Dominant frequency detection: We iterate all bins above the 20 Hz threshold and find the bin with the highest magnitude. The frequency is calculated as
(maxBinIndex * sampleRate) / fftSize.
This is a straightforward peak-detection algorithm. It works well for tonal sounds (music notes, alarms, hums) but reports less meaningful results for broadband noise (fans, rain, traffic) where energy is spread across many frequencies.
Classification system
We classify the current dB reading into human-readable categories using fixed thresholds:
| Range | Classification | Typical sources |
|---|---|---|
| < 20 dB | Silent Room | Near-silent environment, recording studio |
| 20 - 40 dB | Quiet | Library, whisper, calm bedroom |
| 40 - 60 dB | Normal Conversation | Typical speech, home office |
| 60 - 70 dB | Busy Office | Active workplace, multiple conversations |
| 70 - 85 dB | Loud Environment | Heavy traffic, noisy restaurant |
| > 85 dB | Very Loud | Concert, power tools - hearing risk |
These thresholds are based on commonly referenced acoustic guidelines. The boundaries are somewhat arbitrary - a "busy office" can range from 55-75 dB depending on who you ask. We chose values that align with user expectations and common sound meter apps.
Health score calculation
The health score is a 0-100 value indicating how safe the current noise environment is for prolonged exposure. It uses the session's average dB level, not instantaneous peaks.
The scoring formula:
- ≤ 30 dB: Score = 100. Perfectly safe, no hearing risk at any duration.
- 30 - 40 dB: Score decreases by 1 point per dB. A quiet room (35 dB) scores 95.
- 40 - 50 dB: Score decreases by 1.5 points per dB. Normal home (45 dB) scores ~77.
- 50 - 60 dB: Score decreases by 2 points per dB. Conversation level (55 dB) scores ~60.
- 60 - 70 dB: Score decreases by 2 points per dB. TV volume (65 dB) scores ~40.
- 70 - 85 dB: Score decreases by 1.5 points per dB. Vacuum cleaner (75 dB) scores ~22.
- > 85 dB: Rapidly drops toward 0. Anything above 85 dB signals hearing risk with extended exposure.
The score is designed to be conservative. It penalizes early because the goal is awareness: even if 60 dB isn't dangerous, it's noisier than ideal for focus or sleep. The steepest drop happens in the 50-70 dB range where most people spend their time without realizing the cumulative effect.
Limitations & constraints
Browser-based audio measurement has inherent limitations that cannot be fully overcome:
- Browser audio processing. Even when we request AGC/noise suppression disabled, the browser may not honor these constraints. Some browsers apply processing at the OS audio driver level before the Web Audio API ever sees the data.
- Microphone hardware variability. Consumer MEMS microphones have widely varying sensitivity, frequency response, and maximum SPL handling. Two laptops in the same room will produce different readings.
- No calibration. Without a known reference signal (calibrator), we cannot determine the absolute offset for any specific microphone. The +90 offset is a population average, not device-specific.
- Frequency response limitations. Most laptop/phone microphones roll off below 100 Hz and above 8-10 kHz. Low-frequency noise (HVAC rumble, traffic) is underrepresented in readings.
- No A-weighting. Professional meters apply A-weighting to match human hearing perception. We measure unweighted, which slightly overrepresents low and high frequencies that humans perceive as quieter.
- Environmental interference. Desk vibrations, wind on outdoor mics, handling noise, and nearby speakers all contaminate readings.
For these reasons, our readings should be treated as approximate (+/- 3-8 dB) and useful primarily for relative comparison, not absolute measurement.
Browser compatibility
The critical question is whether the browser actually honors our request to disable audio processing. Based on testing:
| Browser | AGC disable | Noise suppression disable | Notes |
|---|---|---|---|
| Chrome (Desktop) | Yes | Yes | Best results. Fully honors constraints. |
| Chrome (Android) | Yes | Yes | Reliable on most devices. |
| Firefox (Desktop) | Mostly | Partial | Some OS-level processing may persist. |
| Safari (macOS) | Inconsistent | Inconsistent | CoreAudio may override constraints. |
| Safari (iOS) | Often ignored | Often ignored | iOS audio stack applies heavy processing. |
| Edge (Desktop) | Yes | Yes | Chromium-based, same as Chrome. |
iOS vs Android: Android generally provides better results for sound measurement because Chrome on Android fully supports audio constraint overrides. iOS applies system-level audio processing (Voice Processing AU) that cannot be bypassed from the browser, resulting in compressed dynamic range and less accurate readings.
For best results, we recommend Chrome on desktop or Android.
Data privacy
Audio data never leaves your browser. Here's exactly what happens technically:
- No server transmission. There are no WebSocket connections, no API calls, no audio upload endpoints. The site is statically generated and served from a CDN.
- Local processing only. The Web Audio API's AnalyserNode runs in the browser's audio rendering thread. It reads the microphone stream, computes FFT and time-domain data, and discards the raw audio immediately.
- No recording. We don't use MediaRecorder. No audio buffers are stored beyond the current 2048-sample analysis frame.
- Static site architecture. There is no backend server. No database. No user accounts. The entire site is pre-built HTML/CSS/JS served from static files.
- No third-party audio services. No analytics on audio content, no cloud speech APIs, no telemetry that includes sound data.
When you stop the meter, the AudioContext is closed, the microphone stream is terminated, and all in-memory audio data is released for garbage collection.
Last reviewed: July 2026. For accuracy assessment, see /accuracy.