Skip to content

Repository files navigation

microwatt

Live voltage, power and current at the Mac headphone jack, with an A-weighted level estimate and a noise-exposure history.

At a normal listening level, 120 Ω headphones draw about 1.5 microwatts. Manufacturers quote output in milliwatts — a thousand times what anyone uses. Hence the name.

中文说明

Black & Gold Aluminium Minimal

Three themes, English and Chinese. Figures rendered from the app itself, not screenshotted:

build/microwatt.app/Contents/MacOS/HeadphoneMeter --render docs

Install

Download microwatt.app.zip from Releases, unzip, and drag microwatt.app to /Applications.

The first launch needs one extra step. The app is signed ad-hoc rather than notarised — notarising requires a paid Apple Developer account — so macOS will refuse it on a double-click. Either:

  • Right-click the app → Open, then confirm; or
  • open it once, then go to System Settings → Privacy & Security and click Open Anyway next to the warning.

You only do this once. Afterwards it opens normally.

It will then ask for two permissions:

Permission Why Without it
Audio recording Reads the audio the player sends to the output. Nothing is recorded or written anywhere. No readings at all
Automation → Music Reads the current track's title and format. Meters work; no track details

What it does

Vrms = fullScale × 10^(volumeDB / 20) × signalRMS
P    = Vrms² / Z(f)        summed per frequency band
SPL  = sensitivityPerVolt + 20·log₁₀(Vrms)

Three quantities go into that, and none of them is guesswork:

Quantity Source
Signal level A CoreAudio process tap reads the PCM Music sends to the output. No virtual audio device, no change to your output selection.
Volume attenuation kAudioDevicePropertyVolumeDecibels — the built-in jack reports its real analogue attenuation in dB, not a slider position.
Full-scale voltage The codec's actual gain stage, read back from the driver. See below.

Reading the gain stage from the hardware

Apple silicon laptops drive the 3.5 mm jack with a Cirrus Logic CS42L84. On insertion it runs DC impedance detection (DCID) — it measures the load — and selects an output mode. The driver publishes the result, and no entitlement is needed to read it:

$ ioreg -c AppleCS42L84Audio -r -l | grep DCIDMode
    "DCIDMode" = "Low Impedance"

Four modes exist (1VRMS, LowImpedance, HighImpedance, HiCapacitance), but only three are voltage tiers — HiCapacitance is amplifier compensation for capacitive loads, with its own sample-rate-dependent registers.

The mode can be read but not set: the register that forces one (DCID_FRC_MANUAL) lives in the kernel. So the app follows the hardware; it never pretends to control it.

Band-resolved measurement

One FFT per block does three jobs at once, because they are the same operation with different per-bin weights:

Weight Fixes
IEC 61672 A-weighting L(A)eq and the NIOSH exposure figure
Impedance curve Z(f) Power and current
Response curve The level estimate

On ordinary pop material, A-weighting comes out about 6 dB below unweighted, which changes the NIOSH allowance by a factor of four. Exposure limits are written in dBA, so this is a correctness matter, not a refinement.

An impedance curve changes power and current only. The amplifier's output impedance (~1 Ω against a 120 Ω load) makes it a voltage source, so the voltage across the headphone — and therefore the level — does not depend on impedance.

The VU meters

Not decorative. The VU meter was standardised in 1942 as ANSI C16.5, then BS 6840 and IEC 60268-17. Every row below is a specification with a test behind it:

swift test --filter VUConformanceAudit

A VU face

Property Standard Measured here
Detector average-responding, full-wave rectified, sine-calibrated form factor π/2√2, exact
Rise 99 % of a step in 300 ms 300.3 ms
Rise, driven as specified — a reference sine through the real detector 300 ms 299.9 – 303.0 ms, 40 Hz – 1 kHz
Overshoot 1 – 1.5 % 1.23 %
Fall same as the rise 300.5 ms
Reading accuracy ±1 dB across the scale 0.012 dB worst
Deflection proportional to voltage; −3 VU at mid-arc 0.5012
Scale −20 to +3 VU, and 0–100 % modulation both drawn
Face type A (VU predominant) for instruments that measure Type A

Three things are easy to get wrong here, and all three were wrong at first.

A VU meter is not an RMS meter. The movement sits behind a full-wave rectifier and responds to mean absolute value. RMS reads high on peaky material — the very thing a VU meter exists to average away. The rectified average is scaled by a sine's form factor so the two agree at the calibration tone.

Two scales, and they check each other. Volume units above the arc, percentage modulation below. Both percentage and deflection are linear in voltage, so the percentage marks come out evenly spaced while the decibel marks crowd left — and 100 % lands exactly on the 0 VU tick. If it misses, the geometry is wrong.

Full travel is +3 VU; the rest position is 0 % modulation, not −20 VU. −20 VU is 10 % modulation, a fourteenth of the way along the arc. Put it against the stop and the whole scale compresses, pushing −3 VU off the centre the standard places it at.

One deliberate departure: the standard calls for black markings on cream. Geometry and ballistics are fixed; the palette is not.

The exposure chart

Hearing damage is cumulative, so the meters cannot answer "how loud have I been listening, and for how long". This can.

The exposure chart explained

In that figure the first half is a dynamic master and the second half a compressed one at the same average level. The solid line barely changes; the gap above it collapses.

Solid line — A-weighted level. How loud it sounds. A-weighting is the ear's own frequency response, and exposure limits are written in it. On pop material it runs about 6 dB below unweighted, which changes the permitted listening time fourfold.

Filled band — peak envelope. The instantaneous maximum in each column.

The gap between them — dynamic range. This is why both are drawn. Two albums at the same average level feel completely different, and the difference is here.

Dashed red — 85 dBA. The NIOSH limit for an eight-hour day, halving every 3 dB above: four hours at 88, two at 91. The header shows the running LAeq and the time left at that level.

Dotted — Leq. The energy average over the window: one number for how loud this has been overall, and what the exposure budget is spent against. It moves; the trace behind it does not.

Axes. Time scrolls right to left, over 1, 3 or 15 minutes. The vertical scale is fixed at 40–95 dBA — the range people listen in, not the range the instrument can measure — so the 85 dBA line never moves and two moments can be compared by eye.

Three minutes at 5 Hz is 900 samples across roughly 570 columns, so the series is reduced to one point per column before drawing. Otherwise the points land a third of a pixel apart and the trace collapses into a band.

Accuracy

Relative values are trustworthy. Cut the volume by 5.3 dB and the reading drops 5.2 dB; the FFT normalisation is pinned by unit tests against analytic sine and white-noise cases, and A-weighting matches the IEC table at every tabulated frequency.

Absolute values rest on one unmeasured constant. Apple publishes 1.25 Vrms below 150 Ω and 3 Vrms from 150 Ω to 1 kΩ; third-party measurements of a MacBook Air report 1.25 / 2.97 / 1.00 V for the three tiers, which agrees. But nothing here is calibrated against a meter. If you own a multimeter, measure a full-scale 1 kHz sine at full volume and enter the value under Calibrated full scale — everything downstream becomes a real measurement.

Impedance and sensitivity are manufacturer figures at 1 kHz. Real drivers are not flat: the HD 560S measures 131.7–240.5 Ω, with the peak in the bass. Enter a curve to fix that.

If the headphone figures are wrong, which readings still are not?

Worth knowing, because the two inputs you type in are the two most likely to be wrong.

Voltage does not depend on impedance at all. The amplifier's output impedance is around 1 Ω against a 120 Ω load, so it behaves as a voltage source: changing the load does not change the volts it delivers.

Reading Depends on the impedance you entered
Output voltage, peak voltage NoV = fullScale × 10^(volumeDB/20) × signalRMS
System volume, headroom No — read from the hardware in dB
VU deflection, dBFS, bit-perfect No — digital signal level
Power, peak power YesP = V²/Z. Halve the impedance and the power doubles
Current YesI = V/Z
Level, exposure, NIOSH time Depends on the sensitivity unit — see below

The sensitivity unit decides whether level is affected. Sensitivity in dB/V is used directly: SPL = sensitivity + 20·log₁₀(V), no impedance anywhere. Sensitivity in dB/mW has to be converted first, and the conversion contains the impedance:

dB/V = dB/mW + 30 − 10·log₁₀(Z)

So on a headphone quoted in dB/V — the HD 560S, IE 900, IE 80, K701 — a wrong impedance costs you power and current and leaves the level estimate alone. On one quoted in dB/mW — HD 600, HD 650, DT 770, Sundara, LCD-2 — the error carries through to level, exposure and the NIOSH time as well. A factor of two in impedance is 3 dB in both cases.

Above all of that sits the unmeasured full-scale voltage, which scales every absolute value together and none of the relative ones.

Requirements

macOS 14.4 or later (process taps), Apple silicon for the hardware gain-stage readback. Other Macs fall back to inferring the stage from rated impedance.

Build

swift build          # library and app
swift test           # 76 unit tests, no audio device needed
./build.sh release   # assembles build/microwatt.app
./package.sh         # …and zips it for distribution

The app is signed ad-hoc. If you have a self-signed code-signing identity in your keychain named microwatt-dev, build.sh will use it instead, which keeps the granted audio permission across rebuilds — ad-hoc signatures derive from the binary's hash, so every rebuild otherwise looks like a new application to macOS.

Design

The decisions behind the interface, and the traps already hit, are in DESIGN.md. Read it before changing the look.

Layout

Sources/MeterCore/        pure measurement, no SwiftUI, fully unit tested
  Audio/                  process tap, sample ring, typed errors
  DSP/                    FFT, A-weighting, curves, meter ballistics
  Devices/                output device, codec gain stage
  Model/                  headphone, physics, exposure maths
Sources/HeadphoneMeter/   SwiftUI app
  Theme/                  three themes: black & gold, brushed aluminium, minimal
  Views/                  screens and meters
Tests/MeterCoreTests/

MeterCore carries no resources and no localisation, so it can be tested headlessly and reused; the UI layer maps its structured errors and enums to localised strings.

Licence

MIT — see LICENSE.


microwatt(中文)

实时显示 Mac 耳机口的电压、功率、电流,附带 A 计权声压估算和噪声曝露曲线。

正常音量下,120 Ω 耳机大约只吃 1.5 微瓦。厂商标称的输出以毫瓦计,是实际用量的 上千倍。名字由此而来。

黑金 铝合金 极简

三个主题,中英双语。文档配图由 app 自己渲染,不是截屏:

build/microwatt.app/Contents/MacOS/HeadphoneMeter --render docs

安装

Releases 下载 microwatt.app.zip,解压后把 microwatt.app 拖进「应用程序」。

第一次打开需要多一步。 这个 app 是 ad-hoc 签名而不是公证过的——公证需要付费的 Apple 开发者账号——所以双击时 macOS 会拒绝。两种办法任选:

  • 右键点 app → 打开,然后确认;或者
  • 先双击一次,再去系统设置 → 隐私与安全性,在警告旁边点仍要打开

只需做一次,之后就能正常双击打开。

然后它会申请两个权限:

权限 用途 不给的后果
录制音频 读取播放器送往输出的音频。不录音,不写入任何地方。 完全没有读数
自动化 → 音乐 读取当前曲目的标题和格式。 表能用,没有曲目信息

VU 表

不是装饰。VU 表 1942 年由 ANSI C16.5 定为标准,后进入 BS 6840IEC 60268-17。下面每一行都是规范,背后都有测试:

swift test --filter VUConformanceAudit

VU 盘面

项目 标准 实测
检波 平均值响应,全波整流,按正弦校准 波形因数 π/2√2,精确
上升 阶跃后 300 ms 到 99 % 300.3 ms
上升(按标准条件:参考正弦经真实检波器) 300 ms 299.9 – 303.0 ms,40 Hz – 1 kHz
过冲 1 – 1.5 % 1.23 %
回落 与上升相同 300.5 ms
读数精度 全刻度 ±1 dB 最差 0.012 dB
偏转 正比于电压;−3 VU 在弧的中点 0.5012
刻度 −20 到 +3 VU,以及 0–100 % 调制 两条都画
盘面型号 A 型(VU 为主),用于测量仪器 A 型

三条特别容易错,而且一开始三条全错了。

VU 表不是 RMS 表。 动圈接在全波整流器后面,响应平均绝对值。RMS 在峰值密集 的素材上读数偏高——而那正是 VU 表要平均掉的东西。整流平均乘以正弦波形因数,两者 在校准音上重合。

两条刻度,互相校验。 弧线上方是音量单位,下方是调制百分比。百分比和偏转都正比 于电压,所以百分比刻度均匀、分贝刻度向左挤压——而且 100 % 正好压在 0 VU 上。压不上 就是几何错了。

满偏是 +3 VU,静止位是 0 % 调制,不是 −20 VU。 −20 VU 是 10 % 调制,在弧长的 十四分之一处。顶在头上会压缩整条刻度,把 −3 VU 挤离标准规定的中点。

一处有意偏离:标准规定米色底黑刻度。几何和弹道是死的,配色不是。

曝露曲线

听力损伤是累积的,所以表盘回答不了「我听了多响、听了多久」。这条曲线可以。

曝露曲线说明

图里前半段是动态母带,后半段是压缩母带,两者平均响度相同。实线几乎没变,而它上方 的缝合上了。

实线——A 计权声压。 你实际感受到的响度。A 计权就是人耳自己的频率响应,所有曝露 限值都以它书写。在流行乐上比不计权低约 6 dB,而这会让允许的聆听时长差四倍。

填充带——峰值包络。 每一列里的瞬时最大值。

两者之间的缝——动态范围。 这就是要画两条的原因。两张专辑可以平均响度相同而 听感天差地别,差别就在这里。

红色虚线——85 dBA。 NIOSH 的每日 8 小时限值,每高 3 dB 允许时间减半:88 dBA 剩 4 小时,91 dBA 剩 2 小时。顶部显示当前 LAeq 和按这个电平还能听多久。

点线——Leq。 窗口内的能量平均:用一个数回答「整体有多响」,曝露额度就是按它 扣的。它会动,它后面的曲线不会。

坐标轴。 时间从右往左滚,可切 1 / 3 / 15 分钟。纵轴固定 40–95 dBA——是人实际 听音的范围,不是仪表的量程——这样 85 那条线永远不动,前后两个时刻可以直接用眼睛比。

3 分钟在 5 Hz 下是 900 个样本画在约 570 列上,所以绘制前先归约成每列一个点。否则 点间距只有三分之一像素,曲线会糊成一条带。

三个量,都不是猜的

来源
信号电平 CoreAudio 进程 tap 直接读 Music 送往输出的 PCM。不需要虚拟声卡,不改你的输出设备
音量衰减 kAudioDevicePropertyVolumeDecibels——内建耳机口汇报真实的模拟衰减 dB,不是滑块位置
满刻度电压 从驱动回读编解码芯片的实际增益档

从硬件读增益档

M 系列 MacBook 的 3.5 mm 口用 Cirrus Logic CS42L84。插入时它跑 DC 阻抗检测 (DCID)实测负载并自选输出档位,驱动把结果发布出来,无需任何特权即可读

$ ioreg -c AppleCS42L84Audio -r -l | grep DCIDMode
    "DCIDMode" = "Low Impedance"

四个模式里只有三个是电压档——HiCapacitance 是针对容性负载的放大器补偿, 有自己一套随采样率变化的寄存器。

档位可读不可写:强制档位的寄存器 DCID_FRC_MANUAL 在内核里。所以这个 app 跟随硬件,绝不假装能控制它。

分频段计算

一次 FFT 同时干三件事——它们本质是同一个操作的不同逐频段加权:

加权 修的是
IEC 61672 A 计权 L(A)eq 和 NIOSH 暴露时长
阻抗曲线 Z(f) 功率和电流
频响曲线 声压估算

普通流行乐上,A 计权比不计权低约 6 dB,NIOSH 允许时长因此差四倍。 暴露限值本来就是按 dBA 写的,所以这是正确性问题不是锦上添花。

阻抗曲线只影响功率和电流。 放大器输出阻抗约 1 Ω,相对 120 Ω 负载几乎是理想 电压源,耳机两端电压与阻抗无关,所以声压不受影响。

精度

相对值可信。 音量降 5.3 dB,读数跟着降 5.2 dB;FFT 归一化有单元测试对着解析解 钉死,A 计权在 IEC 表列的每个频点都对得上。

绝对值建立在一个未实测的常数上。 Apple 公开的规格是 150 Ω 以下 1.25 Vrms、 150 Ω–1 kΩ 之间 3 Vrms;第三方对 MacBook Air 的实测是三档 1.25 / 2.97 / 1.00 V, 对得上。但这里没有任何一项是拿仪表标定过的。有万用表的话,满音量下测一个满刻度 1 kHz 正弦,把值填进「满刻度标定」,之后所有读数就是真实测量。

阻抗和灵敏度是厂商在 1 kHz 的标称值。真实单元并不平直:HD 560S 实测 131.7–240.5 Ω, 峰在低频。填入曲线可以修正。

耳机参数填错的话,哪些读数还是准的

值得说清楚,因为需要你手填的这两个值,恰恰是最容易错的。

电压完全不依赖阻抗。 耳放输出阻抗约 1 Ω,对着 120 Ω 的负载,它是个电压源:换 负载不改变它给出的电压。

读数 是否依赖你填的阻抗
输出电压、峰值电压 —— V = 满刻度 × 10^(音量dB/20) × 信号电平
系统音量、音量余量 —— 从硬件按 dB 读出
VU 指针、dBFS、Bit Perfect —— 数字域信号电平
功率、峰值功率 —— P = V²/Z,阻抗填成一半,功率就翻倍
电流 —— I = V/Z
声压、曝露曲线、NIOSH 时间 取决于灵敏度单位,见下

灵敏度的单位决定声压受不受影响。 dB/V 直接可用:SPL = 灵敏度 + 20·log₁₀(V), 式子里没有阻抗。dB/mW 必须先换算,而换算公式里带阻抗:

dB/V = dB/mW + 30 − 10·log₁₀(Z)

所以标 dB/V 的耳机——HD 560S、IE 900、IE 80、K701——阻抗填错只影响功率和电流, 声压估算不受牵连。标 dB/mW 的——HD 600、HD 650、DT 770、Sundara、LCD-2——误差会 一路传导到声压、曝露曲线和 NIOSH 时间。阻抗差两倍,两种情况下都是 3 dB。

这一切之上还压着未标定的满刻度电压:它同比缩放所有绝对值,但不影响任何 相对变化

要求

macOS 14.4 以上(进程 tap),硬件增益档回读需要 Apple 芯片。其他 Mac 会退回按 标称阻抗推测。

构建

swift build          # 库和 app
swift test           # 76 个单元测试,不需要音频设备
./build.sh release   # 生成 build/Headphone Meter.app

app 是 ad-hoc 签名,首次打开需要右键 →「打开」。它会申请录音权限(读电平)和 「音乐」的自动化权限(读曲目信息)。

许可

MIT,见 LICENSE

About

Live voltage, power and current at the Mac headphone jack. VU meters built to ANSI C16.5.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages