Skip to content

Latest commit

 

History

28 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

[简体中文] | English

ASRInput

A local, real-time speech input system with VAD-based segmentation.

ASRInput 是面向 Windows 的本地语音转文字工具:用 VAD + 声学停顿 自动断句,你说完一句的瞬间就把文字打进当前输入框,同时用一个可拖动的悬浮字幕条实时显示识别结果。全程离线,音频和文本都不离开本机,也不占用剪贴板。


🚀 Features

🎙 Local Real-time Recognition

  • Runs entirely offline, ensuring privacy.
  • VAD-based segmentation:说完一句、停顿一下立刻出字,不必等整段说完(默认停顿阈值 0.3 秒)。
  • Low-latency processing optimized for real-time input.
  • Multi-language support:中文、English、日本語;未勾选的语言会被自动清理(例如没选日语就不会出现假名)。

🖥 Floating Caption Bar

  • Non-intrusive overlay window:无边框悬浮条,默认贴在屏幕底部居中。
  • Transparent background with rounded corners;窗口可拖动、可贴边吸附(四边与四角)。
  • 鼠标移入自动展开(58px)、移开自动收缩(42px),展开/收缩时保持贴边不漂移。
  • Dual UI Modes:日常模式直接上屏;Start-Test.cmd 打开测试窗口,只显示字幕、不向其它程序注入文字。
  • 逐字淡入显示;文字超出可用宽度时自动翻页只显示最新一页;分页只影响显示,不截断录音、也不改变提交边界。

🔊 Microphone + Desktop Audio

  • 托盘 → 音频来源 可分别勾选 麦克风 与 桌面音频(WASAPI loopback),至少保留一个,默认只勾麦克风。
  • 两路分别识别、不做混音,字幕左栏标明来源(Microphone / Desktop)。
  • 真正同时说话保留为两条;麦克风收到的扬声器回声会被抑制,避免同一句重复上屏。

⌨ Global Hotkey Support

  • Quick toggle for enabling/disabling recognition:Ctrl+Shift+H。
  • 切换 转写 / 字幕(是否把文字打进其它程序):Ctrl+Shift+Alt+F9。
  • Hide window with ESC key;两个热键都能在托盘 → 快捷键设置 里修改。

⚙ Adaptive Configuration

  • 断句停顿、能量阈值、人声阈值、单段上限、最短人声、出字速度都能在托盘里调,改动即时生效。
  • 背景噪声自动校准,也可手动重新校准(开始识别后保持安静约 3 秒)。
  • 口吃修复:去掉“我我我”“这个这个”这类重复;按语言清理脚本:未勾选的日语假名 / 韩语谚文不会上屏。
  • System tray integration with comprehensive settings menu.
  • Real-time configuration updates without restart.

🛡 Reliable Text Delivery

  • 用 SendInput 发送 Unicode 键盘事件上屏,不碰剪贴板。
  • 目标窗口不在前台时不会乱打字:文字暂存为“未上屏文字”,托盘 → 附加功能 可查看。
  • 失焦自动暂停(同一窗口内切换焦点立即暂停),回到目标窗口自动恢复。
  • 输入目标可选 锁定当前窗口 或 跟随前台窗口。

📝 Recording & Diagnostics

  • 可选写入 debug/ 录音目录:raw.wav(完整原始 PCM)、segment-XXXX.wav(实际送入识别的片段)、events.jsonl(逐回调 RMS、VAD 判定、分段原因、临时/最终文字、耗时)。
  • 崩溃报告写入 %LOCALAPPDATA%\CyletixASRInput\crashes\。

🧠 Recognition Models

托盘 → 识别模型:

模型 说明
双模型 (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 启动。

📂 Project Structure

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/                                   # 图标与示意图

🎯 How It Works

  1. 采集:麦克风与桌面音频分别采集为 16kHz 单声道;两路各自独立,不混音。

  2. 断句:Silero VAD 判断人声,叠加一层能量停顿门(门限跟随说话音量自适应);流式引擎还有自己的 endpoint 规则。以下条件任一先到就结束当前句:

    结束条件 说明
    停顿达到“断句停顿”时长 默认 0.3 秒;托盘可切 0.1–3.0 秒或“自动”
    流式引擎 endpoint Paraformer / Nemotron 自带的规则
    单段上限 兜底,避免长时间不停顿就不出字(默认 8 秒)
  3. 识别:整句送入所选引擎;双模型模式下再用 SenseVoice 校正一遍。

  4. 显示与上屏:字幕逐字淡入,同时用 SendInput 把字送进目标窗口,句与句之间自动补一个空格。


💻 System Requirements

  • Windows 10 / 11 (x64),包内自带 .NET 运行时,无需另装。
  • 无需联网,也不需要另外安装运行时。
  • 磁盘:完整包解压后约 650MB(模型占约 455MB)。
  • CPU:Paraformer / SenseVoice 很轻;Nemotron 建议限制线程数(实测 4 线程约占 44% CPU,2 线程约 18%)。
  • 内存:常规使用在数百 MB 量级,双源识别大致翻倍。

🔧 Installation

方式一:直接用发布包(推荐)

  1. 从 Releases 下载 ASRInput.zip。
  2. 解压整个 ASRInput 文件夹到任意位置(不要只取出 ASRInput.Desktop.exe,程序依赖同目录的运行时与 models)。
  3. 双击 Start.cmd 开始使用。

方式二:从源码构建,见下方「🔨 Build from source」。

包内已包含 Paraformer 与 SenseVoice 模型,开箱即用;Nemotron 需要自己补模型(见「🧠 Recognition Models」)。


▶️ Run the application

启动方式 作用
Start.cmd 日常使用:识别 + 上屏
Start-Test.cmd 测试模式:打开测试窗口,只显示字幕、不向其它程序注入文字,适合核对识别效果
Start-Debug.cmd 日常使用,同时把录音与事件写进 debug/
ASRInput.Desktop.exe --model <引擎> 指定引擎启动(two-pass / paraformer / sensevoice / nemotron)并写回配置
  • 程序只允许一个实例:重复启动会唤出已有窗口。
  • 指定麦克风:设置环境变量 CYLETIX_MIC_DEVICE 为 WaveIn 设备编号(默认 0),窗口顶部会显示设备名。
  • 退出:托盘 → 退出。

🛠 Configuration

托盘右键就是全部设置:

菜单 内容
显示/隐藏 悬浮字幕条显示或隐藏
开始识别 / 暂停识别 随时暂停;暂停时不采集、不上屏
输出文本 是否把文字打进其它程序(关闭后只显示字幕)
快捷键设置 修改 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 毫秒”这类固定速度。

🎮 Usage Tips

悬浮字幕条

  • 拖动:按住条身拖动,松手自动吸附最近的边或角。
  • 展开/收缩:鼠标移入自动展开,移开自动收起;贴边时保持贴边缩放。
  • 翻页:一行放不下时自动切到最新一页,已读内容不会回滚。
  • 条上的播放按钮就是 开始 / 停止识别。

Hotkeys

  • Ctrl+Shift+H:开始 / 暂停识别
  • Ctrl+Shift+Alt+F9:切换转写 / 字幕
  • ESC:隐藏悬浮条(托盘图标右键可再显示)

上屏注意

  • 目标输入框需要处于前台;焦点在别处时文字不会乱打,而是留作“未上屏文字”。
  • 用「锁定当前窗口」时切到别的窗口会自动暂停;用「跟随前台窗口」则跟着当前焦点走。

🔨 Build from source

主源码在 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。

🔄 Recent Updates (realtime-v12)

New Features

  • 恢复快速预览:中日英多选也使用 Paraformer 首遍;SenseVoice 多语定稿在原行修改,可见文字的出字进度不倒退,最后一句无需下一次开口。中英字幕保持首遍向前播放的原有行为。
  • 个人词库:托盘直接编辑,例如 科大讯飞 | 科大训飞。明确别名在所有模式生效;仅中英双模型允许首遍专名保护,多语模式不能用不支持日语的整段首遍覆盖定稿。词库不训练模型、不猜测同音词。保存于 %LOCALAPPDATA%\CyletixASRInput\personal-vocabulary.txt,打包不携带个人词库。
  • 桌面音频来源:麦克风与系统声音分别识别,扬声器回声自动抑制。
  • 口吃修复、按语言清理脚本、输入目标锁定 / 跟随。
  • 录音与崩溃报告:debug/ 与 %LOCALAPPDATA%\CyletixASRInput\crashes\。

Technical Improvements

  • 分段改为声学停顿:VAD 静音、自适应能量停顿门、流式引擎 endpoint,任一先到即断句。
  • 悬浮条改为单行字幕 + 按宽度翻页,展开/收缩保持贴边。
  • 上屏改用 SendInput Unicode 注入,不再依赖剪贴板。

Bug Fixes

  • 修复流式识别“整段挤成一句、长时间不出字”的问题。
  • 修复字幕与已上屏文字重复、丢字的问题。
  • 修复展开/收缩时窗口漂移、退出后进程残留。

📌 Roadmap

  • ✅ 本地实时识别与声学停顿分段
  • ✅ 麦克风 / 桌面音频双路识别、回声抑制
  • ✅ 多引擎切换与双模型校正
  • ✅ 悬浮字幕(拖动 / 贴边 / 翻页)、全局热键、录音与诊断

后续计划随实际使用反馈调整。


⚖ License

This project is licensed under the MIT License.


🐛 Troubleshooting

Common Issues

现象 处理
启动弹出「启动失败:模型文件缺失」 用完整包解压;或 ASRInput.Desktop.exe --model paraformer 回到已打包的引擎
不说话也一直出字 托盘 → 识别设置 提高「人声阈值」,或用「校准噪声」重采背景
一句话被切得很碎 调大「断句停顿」(0.5 秒以上),或调大「最短人声」
很久不出字 调小「断句停顿」;确认引擎选了 Paraformer 或双模型(SenseVoice 没有流式预览)
文字没进输入框 确认输入框在前台、托盘「输出文本」已勾选;文字会暂存在「未上屏文字」里
桌面音频没声音 确认系统正在播放,并在托盘 → 音频来源 勾上「桌面音频」
CPU 占用高 换用 Paraformer / SenseVoice;Nemotron 减少线程数或关闭双源

Logs

  • 录音与事件:用 Start-Debug.cmd 启动后写在 debug/(raw.wav、segment-XXXX.wav、events.jsonl)。
  • 崩溃报告:%LOCALAPPDATA%\CyletixASRInput\crashes\asr-crash-*.json。
  • 托盘 → 附加功能 → 打开调试目录 可直接跳转。

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

About

A lightweight, local speech recognition tool with VAD-based segmentation for seamless text input.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages