AI 辅助说明:本项目使用 AI 辅助生成,大部分代码由 AI 编写,作者负责审查其行为并保证功能与测试正常。
关于本仓库:本仓库是 Yeson38/Decibel_Monitor 的 fork。原项目及主要开发者是 Yeson38,本 fork 由 Starsky16 独立维护(保留原作者署名)。
本 fork 独立演进:相比原作者仓库的
master已包含下列改动;它们曾以 PR #6~#13 提交上游,但上游自 2026-02 起停止维护,这些 PR 均未合并。现本 fork 独立维护,后续改动不再向上游提 PR。安装请从本仓库的 Releases 下载.cipx。
- 麦克风采样与计算核心重构:抽取共享采样服务、常驻静默捕获流、设备枚举与一次性采样分离;
- 组件与设置重构:设置分布收敛为「测量全局 / 显示随组件 / 提醒在通知」三处,新增插件设置页并把校准上收为全局设置;
- 阈值提醒:新增「分贝提醒」通知提供方与提醒渠道;
- 判定源框架:①超过阈值自动提醒、②超过阈值开筛选窗口并在窗口内按确认热键才提醒(需 KeyboardCapture 插件),各判定源带独立冷却;
- 防抖增强:各判定源可选「连续超阈时长」(与平均窗口正交);判定源②的确认热键改为下拉选择,并新增「应急强制提醒」(连按确认热键若干次即立即提醒);
- 提醒状态点:组件上以形状与呼吸表达当前状态,数字颜色随判据变化并带滞回;
- 时段闸门:课间休息与每节课开头若干分钟内抑制提醒,且抑制期间不占用冷却;
- 临时静默 / 临时开启:托盘菜单与自动化行动可临时停掉或临时打开提醒,到点自动恢复;
- 提醒正文时长可在通知提供方处配置,冷却时长下限提升至 60 秒。
一个用于 ClassIsland 的分贝监测插件,通过一条常驻的低开销捕获流实时读取麦克风峰值并在主界面显示分贝映射值。支持全局校准(将数字音频幅度映射到目标 dBFS),并可通过系统实时计量作为补充。
- 实时显示麦克风分贝值(映射到 0–150 范围以便在 UI 中直观显示)。默认通过一条常驻的低开销捕获流持续计算峰值——数值稳定、无周期性开/关录音造成的闪烁(Windows 麦克风占用图标会常亮而非闪烁)。
- 校准功能:根据目标 dBFS 自动计算并保存全局放大倍数(插件设置页 → 全局校准)。校准时才会进行一次显式采样。
- 阈值提醒:由判定源决定“何时提醒”——判定源①超过阈值即提醒,判定源②超过阈值后开筛选窗口、窗口内按下确认热键才提醒;触发时通过 ClassIsland 通知系统弹出醒目提醒(各判定源自带冷却时间防刷屏)。组件上的提醒状态点同时以形状与颜色表达当前状态。另有时段闸门按课表时段(课间休息、每节课开头若干分钟)抑制提醒,避免课间交谈、上课起立等声音被当成吵闹。
- 临时静默 / 临时开启:不用改设置就能临时停掉或临时打开提醒(托盘菜单「更多选项… → 分贝监测」,或宿主的自动化行动),可选“一节课 / 一个午 / 一天 / 指定分钟”,到点自动恢复、无需重启宿主。
本插件的设置分布在 ClassIsland 的三个位置:
| 位置 | 内容 |
|---|---|
| ① 组件设置(右键组件 → 设置) | 显示偏好:提醒状态点(ShowStatusIndicator)、“分贝:”前缀(ShowDecibelPrefix)、更新频率(UpdateIntervalMs) |
| ② 通知设置(设置 → 通知 → 分贝提醒) | 提醒正文(AlertText) |
| ③ 插件设置页(设置 → Decibel_Monitor) | 全局校准(参考 dB、放大倍数、校准按钮)、测量参数(持续监听、采样时长)、提醒判定(平均窗口、判定源优先级、时段闸门、临时静默 / 临时开启的时长、判定源①/②的启用与阈值/冷却/连续超阈/热键/应急强制提醒)、诊断 |
- .NET 8
- ClassIsland
确保项目正确加载插件。
- 在宿主中将本组件加入布局(或通过插件管理启用)。
- 主界面会显示当前分贝映射值(0–150),数值由全局校准决定(同一麦克风所有组件一致)。
- 进行校准(设置 → Decibel_Monitor 页):
- 将麦克风对准参考声源或播放测试音。
- 将参考滑块设置为目标显示 dB(默认 70,范围 0..150,对应 dBFS -80)。
- 点击“校准”按钮。插件采样一次并计算全局放大倍数,保存后所有组件立即生效。
- 采样或静音表现异常时,可在同一页面使用“捕获设备列表”诊断,或调整测量参数。
- 打开 设置 → Decibel_Monitor 页 → 提醒判定,设置平均窗口时长与判定源优先级。
- 判定源①“自动提醒”:开启后,窗口平均分贝超过阈值即提醒(阈值默认 120,冷却时间默认 600 秒)。
- 判定源②“热键确认”:开启后,窗口平均分贝超过阈值时先开启筛选窗口(默认 10 秒),窗口内按下确认热键才提醒;窗口超时未按键同样进入该判定源的冷却(视为“已经给过一次机会”),因此三角不会长期常亮。该判定源需要宿主安装并启用 KeyboardCapture 插件。
- 提醒正文、正文显示时长与语音在 设置 → 通知 → 分贝提醒 及宿主的提醒设置中配置;本页只决定“何时提醒”。
- 触发提醒时:
- 组件上的提醒状态点变为红色(含义见下方“提醒状态点”);
- 通过 ClassIsland 通知系统弹出醒目提醒;
- 该判定源的冷却时间内不会重复提醒。
- 时段闸门(默认开启,对两个判定源都生效):课间休息期间、以及每节课开始后的若干分钟内不发出通知,用于避开课间交谈、上课起立问好等固定声音造成的误报。
- 抑制期间只停通知:组件上的状态点仍照常显示当前是否超阈值(超阈值显示红色实心方,否则绿色圆)。
- 抑制期间不推进判定源,因此不会占用冷却时间——课间的一次超阈值不会让上课时的提醒失效(这是本功能与“只屏蔽通知”写法的关键区别)。
- 课表未启用或未加载时,本闸门整体不生效,行为与未启用时一致。
- 上课初期保护时长设为
0即关闭该保护;课间抑制可单独关闭。 - 保护起点以插件首次观察到进入上课状态为准(而非课表里的真实开课时间),因此插件在课中启动或重启时会从那一刻重新计时,偏保守(最多少提醒一次)。
- 「冷却时间」就是“这段时间内不再提示”(讨论里常说的“10 分钟内不展示提示”即此项):默认 600 秒(10 分钟),可按需调整,下限 60 秒——一次提醒本身(遮罩 5 秒 + 正文)会盖住状态点约 35 秒,比它更短的冷却期会被提醒整段遮住、用户根本看不到冷却态。
- 连续超阈时长(两个判定源各自可配,默认
0表示关闭):与平均窗口正交——平均窗口先对瞬时值做平滑,本项再要求“平均分贝连续超阈 N 秒”,两者叠加会更抗瞬时误报、但响应更慢(3 秒平均 + 10 秒连续 ≈ 十几秒才响应)。把平均窗口调大并不等于“连续 N 秒”:滑动平均只是把尖峰摊薄,条件仍可能在阈值上下断续成立;连续超阈则要求条件一直成立,尖峰根本不计入。建议先只调其中一项。 - 应急强制提醒(判定源②,默认关闭):开启后,1 秒内连按配置的确认热键若干次(默认 2 次)即立即提醒,无视阈值、冷却期与时段闸门——这是唯一会绕过时段闸门的提醒路径;提醒发出后照样写入该判定源的冷却并关闭筛选窗口,避免紧接着又发一条重复提醒。建议把确认热键设为 F 区功能键,避免打字或游戏时误触发。
- 想“临时停掉 / 临时打开提醒”而不改设置:见下方临时静默 / 临时开启。
三个使用入口共用同一套状态,语义完全一致:
- 托盘菜单:托盘图标右键 →「更多选项…」→「分贝监测」→ 静默本节课 / 静默一个午 / 静默到今日结束 / 临时开启 60 分钟 / 恢复常态;子菜单底部一行显示当前状态与剩余时间。
- 自动化行动:在宿主的“行动”里搜索“分贝提醒”,可添加:
静默分贝提醒(可选:本节课 / 指定分钟数 / 今日结束)恢复分贝提醒(无参数,同时清除静默与临时开启)临时开启分贝提醒(指定分钟数)
- 设置页:
设置 → Decibel_Monitor → 临时静默 / 临时开启只配置两种时长(“本节课”取不到剩余时间时的兜底分钟数、“一个午”的分钟数),入口不在这里。
行为约定:
- 静默期间:不发出通知、不推进判定源(因此不占用冷却时间,静默结束仍会照常提醒),也不消费筛选窗口里的按键确认(静默开始时遗留的窗口会被作废,避免“静默前按的键、静默后才响”)。组件上的状态点照常显示当前是否超阈值——很吵时显示红色实心方,含义与时段闸门抑制期相同(“现在确实很吵,但本时段不提醒”)。
- 临时开启期间:两个判定源都按当前设置照常工作(用于“上课默认禁用 + 需要时临时开启”的用法:把两个判定源都关掉,只在需要时临时开启)。
- 静默与临时开启互斥,后设置的会覆盖前一个;两者均不持久化,宿主重启即恢复常态。
- 到点自动失效,无需重启宿主;「恢复常态」可随时立刻恢复。
组合示例(“上课静默、课间恢复”,触发器由宿主提供):
- 在宿主自动化里新建一个工作流,触发器选“上课”类触发器(
OnClassTrigger)。 - 行动选
静默分贝提醒,时长选“本节课”。 - 再加一个“课间”类触发器(
OnBreakingTimeTrigger),行动选恢复分贝提醒。
组件在分贝值右侧显示一个状态形状。形状表示“当前处于哪一类状态”,填充与呼吸表示附加信息;无采样时不显示任何形状(分贝值显示 N/A);未启用任何判定源时同样不显示形状,但数值照常显示。
| 形状 | 含义 | 说明 |
|---|---|---|
| 绿色圆(半透明) | 正常 | 有采样、判定源已启用且未超过阈值 |
| 红色实心方 | 正在超阈值 | 判定条件成立且尚未进入冷却。注意:提醒在同一拍即发出并写入冷却,而冷却时间的最小可设值是 60 秒,因此实际使用中看不到实心方(会直接进入冷却、显示为空心方)。例外:时段闸门抑制期间、临时静默期间(见第 6 与第 10 条)不写冷却,此时平均分贝超阈值就会显示实心方,表示“现在确实很吵,但当前不提醒” |
| 红色空心方 | 冷却期 | 提醒已发出(含判定源②窗口超时未按键的情形),冷却期内不再重复提醒;冷却期内即使仍超过阈值也显示空心方(空心表示“提醒已发生过”而非“正在触发”)。冷却时间最小 60 秒,是为了让冷却期在一次提醒(遮罩 5 秒 + 正文,见下)结束之后仍有一段能被看见 |
| 橙色三角 | 待热键确认 | 判定源②的筛选窗口已开启,需在窗口内按下热键;窗口剩余时间进入 min(3 秒, 窗口时长 / 4) 后三角会呼吸,提示尽快按键(窗口其余时间静置) |
数字颜色与形状相互独立,只反映“当前值是否满足告警条件”:
- 非冷却期:判据取与触发判定同源的滑动平均值(平均窗口由判定源设置决定)。
- 冷却期:判据改用最近 1 秒的短窗口平均,反映“现在是否还在吵”,而不是整段滑动窗口的旧平均值;此时形状恒为空心方。
- 判据带 2 dB 的迟滞,避免数值在阈值附近反复跳色(进入需超过阈值,退出需低于“阈值 − 2”)。
- 无采样或未启用任何判定源时不设置颜色,沿用宿主默认文字色。
关于“显示值与判定值不一致”(有意保留的口径差异):组件上显示的分贝是瞬时值,而提醒判定(开筛选窗口、自动提醒)与上面的数字颜色判据用的是滑动平均值。因此下面两种错觉都可能出现,属于既定行为、不是缺陷:
- 读数看着不高却变红 / 变三角:窗口平均值已被之前的一小段高值拉高,瞬时值回落但平均仍超阈值。
- 读数明明很高却没有提醒:单次尖峰被平均窗口摊薄,平均值尚未过线;若想减少这类情况,可调小平均窗口(更灵敏)或依赖判定源②的按键确认。
想让两者口径一致就得二选一:显示改成平均值(数字会变得粘滞、响应迟钝),或判定改用瞬时值(单点尖峰就会误触发),两者都被否决,故如实写明由使用者自行取舍。
- 测量得到的线性峰值:
measuredLinear(0..1) - 目标线性值:
targetLinear = 10^(targetDbFS / 20) - 放大倍数:
magnification = targetLinear / measuredLinear
插件会对计算结果做上限保护(默认上限 1024;下限可为 0),以避免极端错误值。
ShowStatusIndicator(bool):是否在组件上显示提醒状态点,默认 true;关闭后仍会正常发出系统通知,只是不在组件上显示状态点(形状含义见“提醒状态点”)。ShowDecibelPrefix(bool):数值前是否显示“分贝:”前缀(如“分贝: 70.0”),默认 true。UpdateIntervalMs(int):数值更新频率(毫秒,运行时会夹取到 100..5000),默认 200。
AlertText(string):提醒正文(通知横幅显示的文字),默认“请保持安静”。OverlayDurationSeconds(int):提醒正文(第二段)的显示时长(秒,面板范围 1..600,运行时夹取 1..600),默认 30。一次提醒由遮罩(固定 5 秒,宿主NotificationContent默认值)与正文两段拼成且文案相同,故一次提醒的总时长 = 5 秒 + 本值;总时长比判定源的冷却时间短时,提醒结束后才能看到冷却期的状态点。启用开关、阈值与冷却不在此处,由插件设置页的判定源负责(避免“判定源已裁定提醒、提供方却因自身阈值不发通知”的双重门槛)。
ReferenceDecibel(double):校准参考(显示刻度 dB 0..150),默认 70(对应 -80 dBFS)。Magnification(double):全局放大倍数,校准后保存,所有组件统一使用。EnableContinuousMonitoring(bool):是否启用“持续监听麦克风”(常驻静默捕获流),默认 true。关闭后仅使用系统实时计量,多数设备会一直显示 0。FallbackCaptureMs(int):显式采样(如校准)的单次录音时长(毫秒),默认 400。SignalThreshold(double):信号检测阈值(存在配置文件中,可在采样异常时调低)。AverageWindowSeconds(double):判定源比较的平均窗口时长(秒),默认 3。SourcePriorityOrder(List<string>):判定源优先级顺序,默认“自动提醒”在前。- 时段闸门(对两个判定源生效):
SuppressAlertDuringBreak(bool,默认 true)、ClassStartProtectionMinutes(int,默认 3,运行时夹取到 0..10,0 表示关闭该保护)。 - 临时静默 / 临时开启:「静默本节课」取不到本节课剩余时间时的兜底时长
SilenceFallbackMinutes(int,默认 45,运行时夹取到 1..1440)、“静默一个午”的时长NoonSilenceMinutes(int,默认 60,同样夹取)。覆盖状态本身不写进设置(不持久化)。 - 判定源①(自动提醒):
AutoSourceEnabled(bool)、AutoSourceThreshold(double,默认 120)、AutoSourceCooldownSeconds(int,默认 600)、AutoSourceSustainSeconds(int,默认 0,运行时夹取到 0..60,0 表示不做持续性要求)。 - 判定源②(热键确认):
HotkeySourceEnabled(bool)、HotkeySourceThreshold(double,默认 120)、HotkeySourceCooldownSeconds(int,默认 600)、HotkeySourceSustainSeconds(int,默认 0,夹取同判定源①)、HotkeyWindowSeconds(int,默认 10)、HotkeyKey(string,默认F5) 与HotkeyCtrl/HotkeyAlt/HotkeyShift/HotkeyMeta(bool)、应急强制提醒ForceAlertEnabled(bool,默认 false) 与ForceAlertPressCount(int,默认 2,运行时夹取到 2..10)。
- 提醒一直没有触发:
- 确认 ClassIsland 的全局通知/语音开关已开启,且 设置 → Decibel_Monitor 页 中至少启用了一个判定源(两个判定源默认都是关闭的)。
- 若启用的是判定源②,确认已安装并启用 KeyboardCapture 插件,且在筛选窗口内按下了配置的确认热键(超时未按键不会提醒)。
- 确认分贝值确实超过了设定阈值(长期显示 0 请参考下一条)。
- 若宿主日志中无“注册提醒渠道:…(超过分贝阈值)”,说明加载的是旧版本插件,请更新插件并重启。
- 课间或刚上课时本就不提醒(时段闸门,默认开启);此时状态点仍会正常变红。如需在这些时段也提醒,可在 设置 → Decibel_Monitor 页 → 时段闸门 关闭“课间期间不提醒”并把“上课初期保护时长”设为 0。
- 也可能正处在临时静默中(托盘 →「更多选项… → 分贝监测」的状态行会显示剩余时间,或再点一次「恢复常态」)。临时静默不持久化,但宿主不重启就会一直生效到截止时间。
- 若两个判定源都是关闭的,可用「临时开启分贝提醒」行动或直接到设置页启用。
- 分贝值长期显示
0.0:- 若关闭了“持续监听麦克风”,则只使用系统实时计量,多数设备会一直为 0;请到 设置 → Decibel_Monitor 页 确认该开关已开启(开启后麦克风占用图标会常亮)。
- 确认宿主应用有麦克风权限(Windows 隐私设置)。
- 确认默认捕获设备已启用并未被独占。
- 在 设置 → Decibel_Monitor 页 使用“捕获设备列表”检查系统设备;增加音量或靠近声源再测。
- 出现“麦克风正在使用”提示且图标闪烁:说明加载的是旧版本插件(旧版周期性开/关录音)。请更新插件;当前版本为常驻监听,图标只会常亮不会闪烁。如不希望常亮,可关闭“持续监听麦克风”。
- 校准结果异常:
- 确认目标单位为 dBFS(数字音频相对量),而非声压级 dB SPL。
- 若测量值接近 0,会导致放大倍数非常大,请提高测试音量或选择更高的目标 dBFS。
- 插件需要访问麦克风进行本地采样,宿主必须授予麦克风权限。
- 插件不会上传或外传音频数据,所有采样仅在本地处理。
- 欢迎提交 issue 或 PR。请遵循仓库中的贡献指南(若存在 CONTRIBUTING.md)提交风格一致的修改。
- 单元测试:
Tests/Decibel_Monitor.Tests覆盖计算器、采样、判定源、仲裁、状态解析与时段闸门等纯逻辑(Windows 环境运行dotnet test Tests/Decibel_Monitor.Tests)。 - Idea来自:HAHAHAHAHAYINING,讨论#561
- 原项目与主要开发者:Yeson38(原作者)
- 本 fork 维护者(协作者):Starsky16
- 参考代码:CIImage