A local, real-time speech input system with VAD-based segmentation.
ASRInput 是面向 Windows 的本地语音转文字工具:用 VAD + 声学停顿 自动断句,你说完一句的瞬间就把文字打进当前输入框,同时用一个可拖动的悬浮字幕条实时显示识别结果。全程离线,音频和文本都不离开本机,也不占用剪贴板。
- Runs entirely offline, ensuring privacy.
- VAD-based segmentation:说完一句、停顿一下立刻出字,不必等整段说完(默认停顿阈值 0.3 秒)。
- Low-latency processing optimized for real-time input.
- Multi-language support:中文、English、日本語;未勾选的语言会被自动清理(例如没选日语就不会出现假名)。
- Non-intrusive overlay window:无边框悬浮条,默认贴在屏幕底部居中。
- Transparent background with rounded corners;窗口可拖动、可贴边吸附(四边与四角)。
- 鼠标移入自动展开(58px)、移开自动收缩(42px),展开/收缩时保持贴边不漂移。
- Dual UI Modes:日常模式直接上屏;
Start-Test.cmd打开测试窗口,只显示字幕、不向其它程序注入文字。 - 逐字淡入显示;文字超出可用宽度时自动翻页只显示最新一页;分页只影响显示,不截断录音、也不改变提交边界。
- 托盘 → 音频来源 可分别勾选 麦克风 与 桌面音频(WASAPI loopback),至少保留一个,默认只勾麦克风。
- 两路分别识别、不做混音,字幕左栏标明来源(
Microphone/Desktop)。 - 真正同时说话保留为两条;麦克风收到的扬声器回声会被抑制,避免同一句重复上屏。
- Quick toggle for enabling/disabling recognition:
Ctrl+Shift+H。 - 切换 转写 / 字幕(是否把文字打进其它程序):
Ctrl+Shift+Alt+F9。 - Hide window with
ESCkey;两个热键都能在托盘 → 快捷键设置 里修改。
- 断句停顿、能量阈值、人声阈值、单段上限、最短人声、出字速度都能在托盘里调,改动即时生效。
- 背景噪声自动校准,也可手动重新校准(开始识别后保持安静约 3 秒)。
- 口吃修复:去掉“我我我”“这个这个”这类重复;按语言清理脚本:未勾选的日语假名 / 韩语谚文不会上屏。
- System tray integration with comprehensive settings menu.
- Real-time configuration updates without restart.
- 用
SendInput发送 Unicode 键盘事件上屏,不碰剪贴板。 - 目标窗口不在前台时不会乱打字:文字暂存为“未上屏文字”,托盘 → 附加功能 可查看。
- 失焦自动暂停(同一窗口内切换焦点立即暂停),回到目标窗口自动恢复。
- 输入目标可选 锁定当前窗口 或 跟随前台窗口。
- 可选写入
debug/录音目录:raw.wav(完整原始 PCM)、segment-XXXX.wav(实际送入识别的片段)、events.jsonl(逐回调 RMS、VAD 判定、分段原因、临时/最终文字、耗时)。 - 崩溃报告写入
%LOCALAPPDATA%\CyletixASRInput\crashes\。
托盘 → 识别模型:
| 模型 | 说明 |
|---|---|
| 双模型 (two-pass) | Paraformer 快速预览中英,SenseVoice 定稿。中日英多选保留预览,并在同一字幕行替换多语定稿;只选日语时直接使用 SenseVoice。 |
| Paraformer | 中英流式识别,出字最快;语言固定为“中英自动”。 |
| SenseVoice | 中日英整段识别,没有流式预览;单段上限最大 4 秒。 |
| Nemotron | 多语言流式识别,需要另行准备模型(约 650MB,默认包不含)。 |
需要中日英自动识别:选择“双模型”,在“语言”里勾选中日英,状态显示“双模型 · 多语定稿”。Paraformer 先出中英预览,日语预览可能是错误中文;SenseVoice 在停顿或最长 4 秒的分段后自动辨认语言,原地替换当前段,不重新播放旧句。转写只提交定稿一次。定稿到达立即采用,5 秒仍失败则停止并提示,不把错误中英预览作为日语输出。只选日语或选择 SenseVoice 时没有流式预览;很短或同句混合语言仍可能识别错误。
模型放在程序目录的 models/ 下,缺少文件时明确报错,不会自动下载:
| 引擎 | 需要的文件 |
|---|---|
| 通用 | silero_vad.onnx |
| Paraformer | sherpa-onnx-streaming-paraformer-bilingual-zh-en/{encoder.int8.onnx, decoder.int8.onnx, tokens.txt} |
| SenseVoice | sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2024-07-17/{model.int8.onnx, tokens.txt} |
| Nemotron | sherpa-onnx-nemotron-3.5-asr-streaming-0.6b-320ms-int8-2026-06-11/{encoder.int8.onnx, decoder.int8.onnx, joiner.int8.onnx, tokens.txt} |
缺少模型时会怎样:
- 启动时缺失:弹出「Cyletix ASRInput 启动失败」并退出,同时写一份崩溃报告。
- 运行中切到缺失的模型:提示“模型切换失败,保留
<当前引擎>”,不崩溃、也不会写进配置。 - 想回到已打包的引擎,可以
ASRInput.Desktop.exe --model paraformer启动。
ASRInput/
├── ASRInput.CSharp/
│ ├── ASRInput.sln
│ └── src/
│ ├── ASRInput.Core/ # 采集、VAD、分段、识别后端
│ │ ├── Asr/RealtimePipeline.cs # 音频线程 + 识别线程、分段状态机
│ │ ├── Asr/EnergyPauseGate.cs # 能量停顿门(跟随说话音量自适应)
│ │ ├── Asr/ParaformerStreamingBackend.cs / SenseVoiceEngine.cs / NemotronStreamingBackend.cs
│ │ ├── Asr/TwoPassBackend.cs # 双模型:流式预览 + 整段校正
│ │ ├── Asr/UtteranceMerge.cs # 相邻片段重叠去重
│ │ └── Audio/MultiSourceCapture.cs / WasapiCapture.cs
│ └── ASRInput.Desktop/ # WPF 界面、托盘、上屏、显示
│ ├── MainWindow.xaml(.cs) # 悬浮字幕条(拖动/贴边/展开收缩)
│ ├── Controls/FadingTextBlock.cs # 逐字淡入
│ ├── Services/TrayService.cs # 托盘菜单
│ ├── Services/TextInjectionService.cs # SendInput 上屏,不碰剪贴板
│ └── ViewModels/MainViewModel.cs # 配置、状态、分段提交
├── diagnostics/ # 构建脚本、测试说明、测试项目、调试会话
├── models/ # 模型目录(构建与运行共用)
├── release/ # 本地发布目录(models、debug 为共享链接)
├── packages/ # 打包产物 ASRInput.zip
└── assets/ # 图标与示意图
-
采集:麦克风与桌面音频分别采集为 16kHz 单声道;两路各自独立,不混音。
-
断句:Silero VAD 判断人声,叠加一层能量停顿门(门限跟随说话音量自适应);流式引擎还有自己的 endpoint 规则。以下条件任一先到就结束当前句:
结束条件 说明 停顿达到“断句停顿”时长 默认 0.3 秒;托盘可切 0.1–3.0 秒或“自动” 流式引擎 endpoint Paraformer / Nemotron 自带的规则 单段上限 兜底,避免长时间不停顿就不出字(默认 8 秒) -
识别:整句送入所选引擎;双模型模式下再用 SenseVoice 校正一遍。
-
显示与上屏:字幕逐字淡入,同时用
SendInput把字送进目标窗口,句与句之间自动补一个空格。
- Windows 10 / 11 (x64),包内自带 .NET 运行时,无需另装。
- 无需联网,也不需要另外安装运行时。
- 磁盘:完整包解压后约 650MB(模型占约 455MB)。
- CPU:Paraformer / SenseVoice 很轻;Nemotron 建议限制线程数(实测 4 线程约占 44% CPU,2 线程约 18%)。
- 内存:常规使用在数百 MB 量级,双源识别大致翻倍。
方式一:直接用发布包(推荐)
- 从 Releases 下载
ASRInput.zip。 - 解压整个
ASRInput文件夹到任意位置(不要只取出ASRInput.Desktop.exe,程序依赖同目录的运行时与models)。 - 双击
Start.cmd开始使用。
方式二:从源码构建,见下方「🔨 Build from source」。
包内已包含 Paraformer 与 SenseVoice 模型,开箱即用;Nemotron 需要自己补模型(见「🧠 Recognition Models」)。
| 启动方式 | 作用 |
|---|---|
Start.cmd |
日常使用:识别 + 上屏 |
Start-Test.cmd |
测试模式:打开测试窗口,只显示字幕、不向其它程序注入文字,适合核对识别效果 |
Start-Debug.cmd |
日常使用,同时把录音与事件写进 debug/ |
ASRInput.Desktop.exe --model <引擎> |
指定引擎启动(two-pass / paraformer / sensevoice / nemotron)并写回配置 |
- 程序只允许一个实例:重复启动会唤出已有窗口。
- 指定麦克风:设置环境变量
CYLETIX_MIC_DEVICE为 WaveIn 设备编号(默认 0),窗口顶部会显示设备名。 - 退出:托盘 → 退出。
托盘右键就是全部设置:
| 菜单 | 内容 |
|---|---|
| 显示/隐藏 | 悬浮字幕条显示或隐藏 |
| 开始识别 / 暂停识别 | 随时暂停;暂停时不采集、不上屏 |
| 输出文本 | 是否把文字打进其它程序(关闭后只显示字幕) |
| 快捷键设置 | 修改 Ctrl+Shift+H 与模式切换热键 |
| 识别模型 | 双模型 / Paraformer / SenseVoice / Nemotron |
| 语言 | 中文 / 英语 / 日语多选(Paraformer 固定“中英自动”) |
| 个人词库 | 每行一个正确词,可用 正确词 | 常见错写 添加自动替换,保存后立即生效 |
| 音频来源 | 麦克风、桌面音频(至少保留一个) |
| 识别设置 | 断句停顿、校正等待、能量阈值、校准噪声、人声阈值、单段上限、最短人声、出字速度 |
| 附加功能 | 打开调试目录、查看未上屏文字、口吃修复、输入目标(锁定当前窗口 / 跟随前台窗口) |
| 退出 | 收尾并退出(带 5 秒看门狗,避免后台残留进程) |
设置保存在 %LOCALAPPDATA%\CyletixASRInput\config-v3.json;未上屏文字暂存在同目录的 pending-input.json。
- 断句停顿:默认 0.3 秒。停顿较短就出字;如果一句话常被切碎,调到 0.5 秒以上。
- 人声阈值:默认 0.6。嘈杂环境(风扇、持续底噪)不易断句时,可试 0.7 / 0.8。
- 能量阈值 / 校准噪声:默认自动跟随环境;换环境后可用「校准噪声」重采约 3 秒背景。
- 单段上限:兜底值,默认 8 秒;SenseVoice 和双模型多语模式最高 4 秒。
- 最短人声:默认 0.15 秒,调大可减少咳嗽、键盘声被识别成字。
- 出字速度:默认自动;也可以固定成“每字 40 毫秒”这类固定速度。
- 拖动:按住条身拖动,松手自动吸附最近的边或角。
- 展开/收缩:鼠标移入自动展开,移开自动收起;贴边时保持贴边缩放。
- 翻页:一行放不下时自动切到最新一页,已读内容不会回滚。
- 条上的播放按钮就是 开始 / 停止识别。
Ctrl+Shift+H:开始 / 暂停识别Ctrl+Shift+Alt+F9:切换转写 / 字幕ESC:隐藏悬浮条(托盘图标右键可再显示)
- 目标输入框需要处于前台;焦点在别处时文字不会乱打,而是留作“未上屏文字”。
- 用「锁定当前窗口」时切到别的窗口会自动暂停;用「跟随前台窗口」则跟着当前焦点走。
主源码在 ASRInput.CSharp/src,构建脚本会同时更新 release/ASRInput 与 packages/ASRInput.zip:
powershell -ExecutionPolicy Bypass -File diagnostics/Build-Realtime.ps1 -Zip- 默认包包含 Paraformer 与 SenseVoice 模型;加
-IncludeNemotron才会把 650MB 的 Nemotron 模型一起打进 ZIP。 release/ASRInput里的models、debug是指向仓库共享目录的链接,因此直接运行时全部模型都可用(含 Nemotron)。- 重建前请先从托盘退出正在运行的程序。
- 使用与测试说明见 diagnostics/TESTING.md。
- 恢复快速预览:中日英多选也使用 Paraformer 首遍;SenseVoice 多语定稿在原行修改,可见文字的出字进度不倒退,最后一句无需下一次开口。中英字幕保持首遍向前播放的原有行为。
- 个人词库:托盘直接编辑,例如
科大讯飞 | 科大训飞。明确别名在所有模式生效;仅中英双模型允许首遍专名保护,多语模式不能用不支持日语的整段首遍覆盖定稿。词库不训练模型、不猜测同音词。保存于%LOCALAPPDATA%\CyletixASRInput\personal-vocabulary.txt,打包不携带个人词库。 - 桌面音频来源:麦克风与系统声音分别识别,扬声器回声自动抑制。
- 口吃修复、按语言清理脚本、输入目标锁定 / 跟随。
- 录音与崩溃报告:
debug/与%LOCALAPPDATA%\CyletixASRInput\crashes\。
- 分段改为声学停顿:VAD 静音、自适应能量停顿门、流式引擎 endpoint,任一先到即断句。
- 悬浮条改为单行字幕 + 按宽度翻页,展开/收缩保持贴边。
- 上屏改用
SendInputUnicode 注入,不再依赖剪贴板。
- 修复流式识别“整段挤成一句、长时间不出字”的问题。
- 修复字幕与已上屏文字重复、丢字的问题。
- 修复展开/收缩时窗口漂移、退出后进程残留。
- ✅ 本地实时识别与声学停顿分段
- ✅ 麦克风 / 桌面音频双路识别、回声抑制
- ✅ 多引擎切换与双模型校正
- ✅ 悬浮字幕(拖动 / 贴边 / 翻页)、全局热键、录音与诊断
后续计划随实际使用反馈调整。
This project is licensed under the MIT License.
| 现象 | 处理 |
|---|---|
| 启动弹出「启动失败:模型文件缺失」 | 用完整包解压;或 ASRInput.Desktop.exe --model paraformer 回到已打包的引擎 |
| 不说话也一直出字 | 托盘 → 识别设置 提高「人声阈值」,或用「校准噪声」重采背景 |
| 一句话被切得很碎 | 调大「断句停顿」(0.5 秒以上),或调大「最短人声」 |
| 很久不出字 | 调小「断句停顿」;确认引擎选了 Paraformer 或双模型(SenseVoice 没有流式预览) |
| 文字没进输入框 | 确认输入框在前台、托盘「输出文本」已勾选;文字会暂存在「未上屏文字」里 |
| 桌面音频没声音 | 确认系统正在播放,并在托盘 → 音频来源 勾上「桌面音频」 |
| CPU 占用高 | 换用 Paraformer / SenseVoice;Nemotron 减少线程数或关闭双源 |
- 录音与事件:用
Start-Debug.cmd启动后写在debug/(raw.wav、segment-XXXX.wav、events.jsonl)。 - 崩溃报告:
%LOCALAPPDATA%\CyletixASRInput\crashes\asr-crash-*.json。 - 托盘 → 附加功能 → 打开调试目录 可直接跳转。
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
