A decibel is not a unit of loudness the way a meter is a unit of length. It is a compression scheme for ratios. Double the acoustic power of a source and the level climbs about 3 dB; multiply the power by 10 and it climbs 10 dB. Ask listeners what a 10 dB jump sounds like and most report roughly twice as loud, which tells you the important part: hearing works on ratios, so the measuring scale is logarithmic too. Sonarish reports approximate sound pressure level in decibels, and for longer sessions it reports LAeq, the A-weighted equivalent continuous level that environmental regulations usually quote.
I keep a mental list of decibel arguments I have watched go wrong. Nearly all of them trace back to one of three confusions: which reference the number is relative to, whether a frequency weighting was applied, and how long the energy was averaged. Everything below is organized around those three questions.
Where the formula comes from
Sound pressure level compares acoustic pressure against a reference of 20 µPa, the conventional threshold of human hearing at 1 kHz. Written out: L_p = 20·log10(p/p0) with p0 = 20 µPa. Why 20 in front of the logarithm instead of 10? Energy is the conserved quantity, and acoustic energy goes as pressure squared. Start from the power form 10·log10(p²/p0²), pull the exponent out of the logarithm, and the 10 becomes 20. Same law, one algebra step apart.
The distinction bites when you read datasheets. Power quantities take a multiplier of 10 inside the level formula. Pressure amplitudes take 20. Mixing the two while converting between datasets leaves you silently wrong by 6 dB, which is a factor of 2 in amplitude and a factor of 4 in energy. I have watched that exact error survive review in a published spec sheet, so now I recompute it every time.
For scale, 20 µPa is about 2 parts in 10 billion of atmospheric pressure. A quiet bedroom at night sits around 30 dB SPL. Normal conversation lands near 60 dB at 1 m, and pain arrives somewhere above 120 dB. That span covers 6 orders of magnitude in pressure and 12 in energy, which is why the logarithm exists: nobody wants a chart axis labeled in trillionths.
Why frequency weighting exists
Your ear does not treat all frequencies equally at moderate listening levels. Low rumble and very high hiss can carry substantial acoustic energy while intruding less than midrange content at the same unweighted level. A-weighting, standardized in IEC 61672, passes the signal through a filter approximating that sensitivity before any level is computed. Energy below about 500 Hz and above about 4 kHz is attenuated. The low end takes it hard: the standard curve sits at -19.1 dB at 100 Hz, -30.2 dB at 50 Hz, and -50.5 dB at 20 Hz, while between 1 and 4 kHz it stays within 1.3 dB of flat.
A motorcycle passing at 80 dB on the unweighted Z-scale might read near 65 dB A-weighted. The physical pressure waveform is unchanged. The filter reflects how most listeners rank the intrusion, and that gap between physics and perception is why two different numbers for the same event can both be correct.
Regulation follows perception. City noise ordinances, workplace exposure limits, and neighbor disputes cite A-weighted metrics: LAeq over 15 min, or LAFmax for the fastest-responding peak, where F names a 125 ms exponential time constant. Comparing a raw unweighted spectrum from a hobby app against a statute written in dBA, without applying the same filter, is the most common amateur mistake in this field. Sonarish applies A-weighting inside its energy integrator so session statistics line up with how regulations are written. Unweighted views remain available for machinery diagnosis, where low-frequency tones carry the information and discarding 19 dB at 100 Hz would be vandalism.
A-weighting has siblings. C-weighting stays nearly flat from about 63 Hz to 4 kHz and appears in impulse metrics such as LCpeak, where the concern is mechanical damage to the ear rather than annoyance. Z means zero weighting, the raw signal. Every Sonarish chart states its weighting in the axis label so a forwarded screenshot keeps its meaning.
Implementing the filter at 48 kHz
On paper the A-curve is an analog transfer function: pole pairs at 20.6 Hz and 12194 Hz, single poles at 107.7 Hz and 737.9 Hz, normalized to 0 dB at 1 kHz. Sonarish captures at 48 kHz, so we map those poles into the digital domain with a bilinear transform and run the result as 3 cascaded biquad sections. Frequency warping near Nyquist bends the response around the 12 kHz pole. At 48 kHz the deviation stays under 0.2 dB across the band a phone microphone can honestly claim, which is fine for a meter that labels itself approximate.
None of this runs inside the audio capture callback. That callback copies samples into a lock-free ring buffer and returns, following the no-malloc, no-locks rules in life on the audio thread. The filter, the squaring, and the accumulation all live on a background processing queue. At these block sizes the filter itself costs almost nothing.
LAeq and why peaks lie
Instantaneous peak level is dramatic and often misleading. One door slam can flash a big number while contributing almost nothing to the energy that disturbs sleep across a whole night. LAeq over an interval T is defined as the constant level that would deliver the same total A-weighted energy as the real fluctuating signal did across that interval. Computationally you square the A-weighted pressure samples, average the squares over the interval, and evaluate 10·log10(mean(p_A²)/p0²); the square root hides inside the logarithm through the same factor-of-2 relationship as before.
The whole accumulator fits in a screenful:
// A-weighted samples in pascals, fed per block
// from the processing queue, never the capture callback
var sumSquares = 0.0
var sampleCount = 0
func accumulate(_ block: [Float]) {
for p in block { sumSquares += Double(p) * Double(p) }
sampleCount += block.count
}
func currentLAeq() -> Double {
let p0 = 20e-6 // 20 µPa
let meanSquare = sumSquares / Double(sampleCount)
return 10 * log10(meanSquare / (p0 * p0))
}
Sonarish lets you choose the integration window: 1 min for quick checks, 15 min for neighborhood noise logs, custom spans for factory walk-throughs. Running LAeq displays alongside short-term percentiles, where LA90 approximates the steady background and LA10 captures the intrusive stretches. The design reflects real use. People want to know whether the air conditioner grew louder over 3 years. The single loudest sample a gust of wind created answers nothing.
Exposure limits and the 3 dB exchange
Occupational health bodies write their limits in exactly these units. The NIOSH recommended exposure limit is 85 dBA as an 8-hour time-weighted average, with a 3 dB exchange rate: every 3 dB added to the level halves the permissible duration, because 3 dB doubles the energy. So 88 dBA buys 4 hours, 91 dBA buys 2, and 100 dBA is down to 15 min. The bookkeeping is plain LAeq arithmetic. A phone app cannot certify a workplace and Sonarish does not pretend to. It can tell you that a table saw sits near 95 dBA at the operator position and that ear muffs cost less than the alternative.
Phone microphones and honest labeling
Professional class-1 sound level meters cost thousands of dollars because their capsules, preamps, and calibration chains are traceable to national standards. A phone microphone is optimized for voice calls and voice assistants. Its capsule was picked for cost, echo-cancellation behavior, and surviving a pocket, and the OS may apply automatic gain unless the raw measurement route is requested explicitly. None of that makes the hardware useless. It makes the hardware something you calibrate and then describe honestly.
We apply a factory offset calibration using reference tones and offer an optional field check: clap at a known distance, compare against a trusted meter if you own one. That tightens typical error into roughly ±2 to 4 dB. Bench note from the lab: 4 phones, 2 iOS and 2 Android, ran 45 min of pink noise stepped from 50 to 90 dB SPL against a class-2 reference meter; raw readings spread 5.8 dB across devices, per-model offsets pulled the spread under ±2 dB, and monthly spot checks over 6 months drifted less than 1 dB. That is sufficient to answer whether this HVAC unit is louder than last month and insufficient to prove compliance in a legal dispute. The UI labels every reading as approximate SPL, permanently.
If you log outdoors, shield the port from wind. A-weighting removes most wind rumble from the reported number while the capsule still sees the full pressure swing, so a reading can look calm while the analog front end is close to overload.
dBFS is a different animal
Digital full scale, written dBFS, measures how close a recording sits to the largest value the analog-to-digital converter can represent. 0 dBFS means clipping. Everything below is headroom. The number says nothing about absolute acoustic pressure in the room, because the mapping between the two depends on microphone sensitivity and every gain stage in between. A typical phone MEMS capsule places 94 dB SPL somewhere near -38 dBFS and overloads acoustically around 120 dB SPL, and both figures shift per model. Voice Memos showing -6 dBFS tells you the recording is hot. It tells you nothing about whether the apartment measures 60 dB A-weighted. Never compare dBFS exports to a municipal noise law written in dBA; the units do not describe the same physical quantity, and no conversion exists without a calibration step.
Our FFT post covers the spectral views these level numbers sit on top of, and machine baseline comparison shows how calibrated level differences reveal mechanical change over months. The meter itself ships in Sonarish, which runs everything on-device and never uploads audio.
Decibel không phải đơn vị đo độ to kiểu mét đo chiều dài. Nó là cách nén tỉ số khổng lồ thành con số so sánh được. Công suất âm gấp đôi thì mức tăng chừng 3 dB. Gấp 10 thì tăng 10 dB. Hỏi người nghe thì tăng 10 dB nghe "to gấp đôi". Chi tiết đó nói lên phần quan trọng nhất: tai người làm việc theo tỉ số nên thang đo cũng phải logarit. Sonarish hiển thị mức áp suất âm xấp xỉ theo decibel; session dài thì có thêm LAeq, mức liên tục tương đương đã qua A-weighting mà quy chuẩn môi trường hay trích dẫn.
Mình giữ trong đầu một danh sách những cuộc cãi nhau về decibel đi sai hướng. Gần như tất cả quy về ba chỗ nhầm: so với mốc nào, đã qua bộ lọc tần số chưa hoặc lấy trung bình năng lượng trong bao lâu. Mọi thứ bên dưới xoay quanh đúng ba câu đó.
Công thức từ đâu ra
Mức áp suất âm so áp suất với mốc 20 µPa, ngưỡng nghe quy ước ở 1 kHz. Viết đầy đủ: L_p = 20·log10(p/p0) với p0 = 20 µPa. Vì sao nhân 20 chứ không phải 10? Vì năng lượng mới là đại lượng bảo toàn, mà năng lượng âm tỉ lệ bình phương áp suất. Xuất phát từ dạng công suất 10·log10(p²/p0²), kéo số mũ ra khỏi log, 10 thành 20. Cùng một định luật, cách nhau một bước đại số.
Chỗ này hay cắn khi đọc datasheet. Đại lượng công suất nhân 10 trong log. Biên độ áp suất nhân 20. Trộn hai công thức lúc đổi giữa các bộ dữ liệu là sai âm thầm 6 dB: gấp 2 về biên độ, gấp 4 về năng lượng. Mình từng thấy đúng lỗi này lọt qua review trong một spec đã công bố nên giờ lần nào cũng tự tính lại.
Để hình dung: 20 µPa cỡ 2 phần 10 tỷ áp suất khí quyển. Phòng ngủ yên tĩnh ban đêm quanh 30 dB SPL. Nói chuyện bình thường gần 60 dB ở khoảng cách 1 m. Ngưỡng đau đâu đó trên 120 dB. Dải đó trải 6 bậc độ lớn về áp suất và 12 bậc về năng lượng. Log tồn tại để trục đồ thị khỏi phải ghi số phần nghìn tỷ.
Vì sao phải có trọng số tần số
Tai không đối xử công bằng với mọi tần số ở mức nghe vừa. Ù trầm và rít rất cao có thể mang nhiều năng lượng mà vẫn ít gây khó chịu hơn dải mid cùng mức chưa weight. A-weighting, chuẩn hóa trong IEC 61672, cho tín hiệu qua bộ lọc mô phỏng độ nhạy của tai trước khi tính mức. Năng lượng dưới khoảng 500 Hz và trên khoảng 4 kHz bị suy giảm. Phía trầm bị nặng nhất: -19,1 dB ở 100 Hz, -30,2 dB ở 50 Hz và -50,5 dB ở 20 Hz. Từ 1 đến 4 kHz đường cong gần phẳng, lệch không quá 1,3 dB.
Xe máy chạy qua đo 80 dB thang Z chưa weight có thể chỉ còn gần 65 dB A-weighted. Dạng sóng áp suất y nguyên. Bộ lọc chỉ phản ánh cách đa số người nghe xếp hạng độ phiền, nên hai con số khác nhau cho cùng một sự kiện vẫn đều đúng.
Quy định đi theo cảm nhận. Quy chuẩn ồn đô thị, giới hạn tiếp xúc nơi làm việc hay tranh chấp hàng xóm đều trích metric A-weighted: LAeq 15 phút hoặc LAFmax cho đỉnh phản hồi nhanh, chữ F là hằng số thời gian mũ 125 ms. Lấy phổ thô chưa weight từ app đem so với luật viết bằng dBA mà không qua cùng bộ lọc là lỗi amateur phổ biến nhất mảng này. Sonarish áp A-weighting ngay trong bộ tích năng lượng để thống kê session khớp với cách luật được viết. View chưa weight vẫn giữ cho chẩn đoán máy móc: tone tần thấp mang thông tin chẩn đoán, vứt 19 dB ở 100 Hz thì còn gì mà đọc.
A-weighting có anh em. C-weighting gần phẳng từ khoảng 63 Hz đến 4 kHz, xuất hiện trong metric xung như LCpeak, nơi mối lo là tổn thương cơ học của tai chứ không phải độ phiền. Z nghĩa là không weight, tín hiệu thô. Mọi biểu đồ Sonarish ghi rõ loại weighting trên nhãn trục để screenshot chuyển tiếp đi vẫn giữ nguyên nghĩa.
Cài bộ lọc ở 48 kHz
Trên giấy, đường cong A là hàm truyền analog: cặp pole ở 20,6 Hz và 12194 Hz, pole đơn ở 107,7 Hz và 737,9 Hz, chuẩn hóa 0 dB tại 1 kHz. Sonarish thu ở 48 kHz nên bọn mình ánh xạ pole sang miền số bằng bilinear transform rồi chạy thành 3 khâu biquad nối tầng. Warping tần số gần Nyquist làm cong đáp ứng quanh pole 12 kHz. Ở 48 kHz độ lệch dưới 0,2 dB trong dải mà micro điện thoại dám nhận, đủ tốt cho một máy đo tự dán nhãn xấp xỉ.
Không phép tính nào ở trên chạy trong callback thu âm. Callback chỉ copy sample vào ring buffer lock-free rồi thoát, theo đúng luật không malloc không lock trong bài audio thread. Bộ lọc, phép bình phương và phép cộng dồn nằm hết trên queue xử lý nền. Ở cỡ block này, bản thân bộ lọc gần như miễn phí CPU.
LAeq và vì sao peak hay lừa
Mức đỉnh tức thời trông kịch tính và dễ gây hiểu nhầm. Một cú sập cửa nháy lên con số to trong khi đóng góp gần như bằng không vào tổng năng lượng phá giấc ngủ cả đêm. LAeq trên khoảng T định nghĩa là mức không đổi mang đúng tổng năng lượng A-weighted bằng tín hiệu thật dao động trong khoảng đó. Về tính toán: bình phương các sample áp suất đã weight, lấy trung bình rồi tính 10·log10(mean(p_A²)/p0²). Phép căn bậc hai ẩn sẵn trong log nhờ quan hệ hệ số 2 ở trên.
Cả bộ cộng dồn gọn trong một màn hình:
// sample đã A-weight tính bằng pascal, nạp theo block
// từ queue xử lý, không bao giờ từ callback thu âm
var sumSquares = 0.0
var sampleCount = 0
func accumulate(_ block: [Float]) {
for p in block { sumSquares += Double(p) * Double(p) }
sampleCount += block.count
}
func currentLAeq() -> Double {
let p0 = 20e-6 // 20 µPa
let meanSquare = sumSquares / Double(sampleCount)
return 10 * log10(meanSquare / (p0 * p0))
}
Sonarish cho chọn cửa sổ tích phân: 1 phút cho check nhanh, 15 phút cho log ồn khu dân cư, span tùy chỉnh khi đi khảo sát xưởng. LAeq chạy hiện song song percentile ngắn hạn: LA90 xấp xỉ nền ổn định, LA10 bắt các đoạn xâm lấn. Thiết kế bám câu hỏi thật của người dùng. Muốn biết điều hòa có to dần sau 3 năm không. Còn cái sample to nhất do một cơn gió giật tạo ra thì chẳng trả lời được gì.
Giới hạn tiếp xúc và quy tắc đổi 3 dB
Các tổ chức y tế nghề nghiệp viết giới hạn bằng đúng những đơn vị này. NIOSH khuyến nghị trần 85 dBA theo trung bình trọng số thời gian 8 giờ, kèm tỉ lệ đổi 3 dB: cứ thêm 3 dB thì thời gian cho phép giảm một nửa vì 3 dB là gấp đôi năng lượng. Vậy 88 dBA còn 4 giờ, 91 dBA còn 2 giờ, 100 dBA chỉ còn 15 phút. Toàn bộ sổ sách là số học LAeq thuần. App điện thoại không chứng nhận được nơi làm việc và Sonarish cũng không giả vờ. Nó chỉ nói được máy cưa bàn của bạn quanh 95 dBA ở vị trí đứng máy và chụp tai chống ồn rẻ hơn nhiều so với phương án còn lại.
Micro điện thoại và chuyện dán nhãn thật thà
Máy đo class-1 chuyên nghiệp giá hàng nghìn đô vì capsule, preamp và chuỗi calibrate truy vết được về chuẩn quốc gia. Micro điện thoại sinh ra cho cuộc gọi và trợ lý giọng nói. Capsule được chọn vì giá, vì khử echo, vì sống sót trong túi quần; hệ điều hành còn có thể tự chỉnh gain nếu không xin route đo thô. Không vì thế mà phần cứng vô dụng. Chỉ là phải calibrate xong rồi mô tả cho trung thực.
Bọn mình áp offset calibrate từ nhà máy bằng tone chuẩn, kèm bước check hiện trường tùy chọn: vỗ tay ở khoảng cách biết trước, so với máy đo tin cậy nếu bạn có. Cách đó siết sai số điển hình về khoảng ±2 đến 4 dB. Ghi chú bench: 4 điện thoại, 2 iOS và 2 Android, chạy 45 phút pink noise bậc thang từ 50 đến 90 dB SPL so với máy class-2; số thô lệch nhau 5,8 dB giữa các máy, offset theo model kéo về dưới ±2 dB, spot check hàng tháng suốt 6 tháng drift chưa tới 1 dB. Đủ để trả lời cục HVAC tháng này có to hơn tháng trước không. Không đủ để chứng minh tuân thủ trong tranh chấp pháp lý. UI ghi SPL xấp xỉ trên mọi số đo, vĩnh viễn.
Đo ngoài trời thì che cổng micro khỏi gió. A-weighting xóa gần hết tiếng ù của gió khỏi con số hiển thị trong khi capsule vẫn hứng nguyên biên độ áp suất, nên số đo có thể trông hiền trong lúc front-end analog sắp quá tải.
dBFS là con thú khác
Full scale số, viết là dBFS, đo bản ghi cách trần của bộ ADC bao xa. 0 dBFS là clip. Dưới đó là headroom. Con số này không nói gì về áp suất âm tuyệt đối trong phòng vì ánh xạ giữa hai bên phụ thuộc độ nhạy micro và mọi tầng gain ở giữa. Capsule MEMS điện thoại điển hình đặt 94 dB SPL quanh -38 dBFS và quá tải âm học quanh 120 dB SPL; hai con số xê dịch theo từng model. Voice Memos hiện -6 dBFS nghĩa là bản ghi đang nóng. Còn căn hộ có 60 dB A-weighted hay không thì nó chịu. Đừng bao giờ đem file dBFS so với luật ồn thành phố viết bằng dBA; hai đơn vị mô tả hai đại lượng vật lý khác nhau và không có phép đổi nào nếu thiếu bước calibrate.
Bài FFT nói về các view phổ nằm dưới mấy con số mức này, còn so baseline máy cho thấy chênh lệch mức đã calibrate phát hiện được thay đổi cơ khí qua nhiều tháng. Bản thân máy đo nằm trong Sonarish, chạy toàn bộ trên máy và không bao giờ upload audio của bạn.