﻿==============================================================
  业余无线电通联辅助工具 · 便携版
  需自装 Python / 首次运行联网下载模型
==============================================================

一、怎么运行
--------------------------------------------------------------
1. 双击本目录下的「启动.bat」
2. 稍等 10~60 秒（首次启动要把识别模型读进内存），
   浏览器会自动打开 http://127.0.0.1:8000
3. 用完直接关闭那个黑色命令行窗口，程序即退出。

需要先安装 Python 3.13 并双击「安装依赖.bat」装好依赖（详见「安装Python说明.txt」）；首次运行会联网下载识别模型。
整个文件夹可以拷到 U 盘或任意路径下运行（路径含中文也没问题）。


二、使用前必须做的一步：选择音频来源
--------------------------------------------------------------
程序支持两种音频来源，改 app\config.yaml 的 audio_source.type 切换，
改完重启生效。两种方式都需要一根 RTL-SDR 天线（或用其它已解调好的音频）。

【方式 A】sdr —— 默认，直连硬件，不再需要 SDR++ 和 VB-Cable
  链路：天线 → RTL-SDR → 本程序（内置 rtl_fm 解调）

  1. 确认 app\tools\rtl-sdr 下有 rtl_fm.exe、rtl_test.exe、
     rtlsdr.dll、msvcr100.dll、pthreadVC2.dll。
     缺了就去 https://github.com/rtlsdrblog/rtl-sdr-blog/releases
     下载 Release.zip，把里面 x64 目录的**整个内容**复制到该目录
     （你的 V4 必须用这个修改版驱动，不要用 osmocom 上游版）。
  2. 若 config.yaml 的 audio_source.type 不是 sdr，改成 sdr
  3. 完全退出 SDR++：一根 RTL-SDR 同一时刻只能被一个程序占用，
     否则会报 usb_claim_interface error -6
  4. 重启程序 → 顶部「频率」页 → 「刷新设备」确认能看到设备
  5. 填频点（98.700 这类格式），选调制，点「调谐」即可开始采集：

       WFM  宽带调频 ±75kHz  → 87.5~108MHz 调频广播（听收音机选这个）
       NFM  窄带调频 ±2.5kHz → 业余中继 / 对讲机（144/430MHz）
       AM   调幅             → 民航 118~137MHz

     调好后可以点「☆ 保存到频率清单」存成常用频率，之后从清单里一键切换。
     FM 广播若觉得声音发闷或失真，把「设备」里的 IQ 采样率从 240kHz 调到
     1024kHz 再试（宽带信号在更高采样率下有余地，代价是 CPU）。

【方式 B】vbcable —— 链路长但适应性强
  链路：天线 → RTL-SDR → SDR++ 解调 → CABLE Input → CABLE Output → 本程序

  1. 下载 VB-Cable：https://vb-audio.com/Cable/ （VBCABLE_Driver_Pack*.zip）
  2. 解压后右键 VBCABLE_Setup_x64.exe → 以管理员身份运行 → Install Driver
  3. 重启电脑
  4. 打开「声音设置 → 更多声音设置 → 录制」，确认出现 CABLE Output
  5. CABLE Input / CABLE Output 的「属性 → 高级」里，
     采样率都设为「16 位, 48000 Hz」，并取消勾选「允许应用程序独占控制」
  6. 系统默认播放 / 录制设备保持原样不动
  7. 打开 SDR++ → 音频输出设备选 CABLE Input（采样率 48000）
  8. 把 config.yaml 的 audio_source.type 改成 vbcable

  启动后若日志提示「未找到匹配的输入设备」，用浏览器打开
  http://127.0.0.1:8000/api/devices 查看输入设备列表，把准确名称填到
  app\config.yaml 的 audio_source.vbcable.device_name 里。

  提示：调频点 / 改调制 / 改增益都会重启 rtl_fm，有约 0.1~0.3 秒的音频中断；
  静噪是软件门槛，调节时实时生效、不中断。


二·五、两种工作模式（「频率」页最上面，或底部状态栏）
--------------------------------------------------------------
「听」和「录」是两件独立的事。监听可以随时静音（比如你在回放录音），
完全不影响录音；录音没开时也照样能听。两种模式只是两个开关的一组默认值。

【实时】坐在电脑前听
  · 服务端出声（默认开）：声音从**运行程序的这台电脑**的声卡放出来，
    走系统默认播放设备。有信号才出声（静噪控制），不会一直沙沙响。
  · 录音手工启停：点「开始录音」边录边写；单个文件到 5 分钟会自动开新文件
    **继续录**（不中断），音量与时长在底部状态栏能随时看到并停止。
  · 切频会**中断录音**——一个文件只对应一个频点，需要你重新点开始。
  · 手工录音默认**不转写**（长录音转写慢且常无必要），
    想转就在「采集记录」里对该条点「手工录音 · 点此转写」。

【守听】人在别处，让它自己留档
  · 自动录音（默认开）：有信号就自动切一段存下来，一句话一个文件。
  · 默认不出声。想边守听边听，把监听打开即可。
  · 切频只把当前这句落盘，自动录音不中断（每段自带自己的频点）。
  · 录到的每句默认自动送转写。

浏览器只在**点击回放录音**时才出声；回放期间服务端监听会自动静音，
回放结束再恢复，录音全程不受影响。

两个常见问题：
· 监听开着但没声音
  1) 顶部「频率」页会红字提示具体原因（打不开输出设备 / 输入输出同设备）。
  2) 确认**系统默认播放设备**是扬声器或耳机，不是 CABLE Input ——
     指向 CABLE Input 会把声音送进虚拟声卡（既听不见，还可能形成回环），
     程序检测到「输入输出是同一个设备」会直接拒绝开启监听。
· 想让监听换个声卡（比如插耳机）
  改 app\config.yaml 的 monitor.device_index（留空 = 系统默认输出）。
  注意同一块声卡在 Windows 里会以 MME/WASAPI 等接口各出现一次，
  程序默认挑 WASAPI 的那个（延迟最低）。


三、识别引擎与模型（首次运行联网下载，之后离线）
--------------------------------------------------------------
两个引擎都支持，改 app\config.yaml 的 transcription.engine
即可切换，改完重启程序生效：

  engine: funasr          → 阿里达摩院 Paraformer（约 950 MB）
                            中文识别率更高，当前默认
  engine: faster_whisper  → Whisper small（约 470 MB）
                            通用多语言

关于联网：包内未附带模型，首次运行会按上面的 engine 自动联网下载
（funasr 从 ModelScope、faster_whisper 从 HuggingFace 镜像 hf-mirror.com，国内均可直连），
下载只需一次、之后完全离线。启动器已预置 HF_ENDPOINT=https://hf-mirror.com 等镜像变量，
无需你手动配置。


四、数据存在哪
--------------------------------------------------------------
录音与转写结果都在 app\storage 下：
  app\storage\raw\YYYY\MM\DD\*.wav     原始录音
  app\storage\db\repeater.db           转写文本数据库

想清空历史记录，直接删除 storage 目录里的内容即可（程序会自动重建）。


五、出问题先看这几条
--------------------------------------------------------------
· 双击后窗口一闪就没了
  说明启动出错。打开命令行进入本目录，手动执行「启动.bat」查看报错。

· 浏览器打不开 / 一直转圈
  模型还在加载。看命令行窗口是否出现「模型加载完成」，之后刷新页面。

· 日志出现 WinError 1114（torch 相关）
  系统缺 VC++ 运行库。安装「Microsoft Visual C++ 2015-2022
  Redistributable (x64)」后重试。

· 提示 8000 端口被占用
  已有实例在运行，程序会直接打开浏览器；或改 app\config.yaml 的 server.port。

· 采集不到声音 / 识别不出内容
  vbcable 方式：多半是 VB-Cable 没装好，或 SDR++ 输出设备没选 CABLE Input，
  按第二节方式 A 逐条核对。另外可调大 config.yaml 的
  audio_source.vbcable.vad_mode 与采集参数。
  sdr 方式：先看顶部「频率」页的提示——若显示「未就位 rtl_fm.exe」，
  按第二节方式 B 放齐四个文件；若显示 rtl_fm 的报错信息，
  通常是 SDR++ 还占着设备，或 Zadig 驱动装到了错误的接口上。

· SDR 直连方式报 usb_open error -3 / Failed to open rtlsdr device
  说明设备打不开。按顺序排查：
  1. 先看顶部「频率」页的红色提示，程序会把 rtl_fm 的原始报错翻译成具体步骤。
  2. 完全退出 SDR++ / SDR# / HDSDR 等 SDR 软件 —— 一根 RTL-SDR 同一时刻
     只能被一个程序打开，SDR++ 即使没在播放、只是开着也会占住设备。
  3. 检查任务管理器里有没有残留的 rtl_fm.exe。关掉命令行窗口属于强制结束，
     子进程有可能没跟着退出；程序下次启动会自动清理它们（见 config.yaml 的
     audio_source.sdr.kill_orphans_on_start）。
  4. 以上都不行，就是驱动没换成 WinUSB：用 Zadig 重装，**只对 Interface 0 操作**。
     报错里那句 "installing the udev rules file rtl-sdr.rules" 是 Linux 文案，
     Windows 上不用管。

· 顶部没有「频率」页
  说明前端是旧版本。重新运行打包脚本生成最新前端即可。


六、适用范围
--------------------------------------------------------------
仅用于个人学习与通联辅助，请遵守当地无线电管理法规，
录制内容仅供个人回顾。
