XiStudio · Sink 模块前端实现说明 v1.1
文档定位
本文档以 frontend_vue3 当前代码为准,描述 Sink 模块在前端中的真实实现状态。重点覆盖 sink_v1、两种输出模式、共享设备 Store、日志录制参数,以及运行时切换行为。
本版结论
当前 Sink 不是 Source 文档的镜像版本。它没有 sourceType、没有文件上传,也没有拆分后的 sink_* 体系;它的核心是 outputMode、设备输出切换,以及设备输出场景下的 WAV 日志录制。
1. 实现入口
| 类型 | 文件 | 作用 |
|---|---|---|
| 调参对话框 | src/components/SinkTuningDialog.vue |
Sink 主交互入口 |
| 内建模块定义 | src/stores/moduleLibrary.ts |
定义 sink_v1 |
| 链路与参数补齐 | src/stores/linkStore.ts |
默认加点、补齐日志参数 |
| 设备缓存 | src/stores/deviceStore.ts |
输出设备列表缓存与预取 |
| 模块库面板 | src/components/ModuleLibraryPanel.vue |
展示 sink 分类模块 |
2. 当前模块模型
2.1 sink_v1
sink_v1 是当前唯一默认 Sink 入口,定义如下:
| 项目 | 当前实现 |
|---|---|
mode |
builtin_normal |
category |
sink |
| 输入端口 | 1 个动态输入端口 |
| 输出端口 | 无 |
默认 outputMode |
wav |
默认 runMode |
pc |
模块定义中当前可见的主要 tunable 参数:
outputModewavPathwavFilenameoutputDeviceIdrunModechannels
2.2 没有拆分态 Sink 模块
与 Source 已出现拆分 source_*_v1 不同,当前前端代码中没有等价的 sink_wav_v1、sink_device_v1 等拆分内建模块。产品层面应视为:
sink_v1是唯一产品入口;- 输出能力通过
outputMode在单模块内部切换; - 设备输出与调试录制是一个统一界面中的两个分支能力。
3. 调参窗口的真实行为
3.1 固定骨架
SinkTuningDialog.vue 的界面结构为:
- 顶部启用/禁用按钮
- 标题与关闭按钮
PresetPanel- 输出模式切换栏
- 当前激活状态栏
- 对应模式的参数区域
3.2 输出模式切换
当前前端写死了 2 个输出模式:
| 值 | 标签 |
|---|---|
wav |
WAV 文件 |
device |
声卡输出 |
切换逻辑:
- 先写入
linkStore.setParamValue(instanceId, 'outputMode', mode); - 再发送 WebSocket
set_param; - 若切换到
device且当前没有缓存输出设备,会立即拉取设备列表; - 若引擎正在运行且模式发生变化,调用
engineStore.startEngine()重启引擎。
3.3 WAV 输出分支
WAV 模式当前提供:
| 参数 | 说明 |
|---|---|
runMode |
pc / dsp |
wavPath |
输出目录 |
wavFilename |
文件名 |
wavFullPath |
由前端拼接显示的完整路径预览 |
这里的 wavFullPath 只是界面预览值,不是单独下发给后端的字段。
3.4 Device 输出分支
设备输出分支当前提供:
| 能力 | 当前实现 |
|---|---|
| 设备刷新 | 调用 devStore.fetchOutput() |
| 驱动类型 | DirectX / ASIO |
| 设备选择参数 | outputDeviceId |
| 错误反馈 | 监听 set_param_ack 失败消息,显示 devError |
| 设备列表来源 | deviceStore.outputDevices() |
3.5 WAV 日志录制
这是 Sink 当前最关键的差异化能力:
| 参数/状态 | 说明 |
|---|---|
wavLogEnabled |
是否开启日志录制 |
wavLogPath |
日志目录 |
wavLogFilename |
日志文件名 |
wavLogFullPath |
界面预览的完整日志路径 |
启用后,界面会展开额外的路径与文件名输入项,用于记录设备输出数据。
4. 设备 Store 与 WebSocket 行为
4.1 deviceStore.ts 的角色
Sink 并不自己维护输出设备列表,而是复用全局 deviceStore:
- 设备按驱动类型缓存;
outputDriverType默认是DirectX;- WebSocket 连接成功后会预取输出与输入设备;
fetchOutput(driverType)会发送get_audio_devices请求并在回包时落库。
4.2 主动发送的消息
| 场景 | 消息 |
|---|---|
| 切换输出模式 | set_param |
| 修改路径/文件名 | set_param |
| 刷新输出设备列表 | get_audio_devices(direction: 'output') |
| 运行中切换输出设备 | set_audio_device |
4.3 监听的消息
| 消息 | 用途 |
|---|---|
audio_devices / audio_device_list |
回填输出设备列表 |
set_param_ack |
检查输出设备切换失败 |
5. 与链路系统的关系
5.1 默认工程骨架
linkStore.addDefaultModules() 会自动向空链路加入 source_v1 与 sink_v1,因此 Sink 是每个默认工程都会拥有的终点。
5.2 动态输入继承
sink_v1 的输入端口不是固定规格,而是通过 propagatePortInfo() 继承上游模块的实际输出规格:
- 通道数继承上游;
- 采样率继承上游;
- blockSize 继承上游;
- 数据类型与信号类型继承上游。
5.3 日志参数的默认补齐
linkStore.fillModuleDefaultParamValues() 会对 sink_v1 额外补齐:
| 参数 | 默认值 |
|---|---|
wavLogEnabled |
false |
wavLogPath |
./output |
wavLogFilename |
wasapi_log.wav |
这意味着日志录制能力虽然没有完整体现在 sinkModule.params.tunable 中,但已经被链路系统视为正式产品参数。
6. 模块库与模式差异
6.1 模块库显示
ModuleLibraryPanel.vue 在正常模式下会显示 sink 分类下的内建模块;在兼容模式下也会保留 source / sink 两类基础入口。
6.2 与 Source 的非对称关系
| 主题 | Source | Sink |
|---|---|---|
| 入口模式字段 | sourceType |
outputMode |
| 子能力数量 | 4 类 | 2 类 |
| 拆分模块 | 已存在 source_*_v1 |
暂无 sink_*_v1 |
| 设备相关 | 输入设备采集 | 输出设备播放 |
| 调试附加能力 | 无统一日志分支 | 有 wavLogEnabled |
7. 当前已知差距
| 主题 | 当前状态 |
|---|---|
| 拆分 Sink 模块 | 未实现 |
| 独立状态灯体系 | 未在当前代码中看到 |
| 输出设备驱动列表 | UI 仅暴露 DirectX / ASIO,但 Store 还会预取 wasapi |
runMode 显示位置 |
仅在 wav 分支显式展示 |
8. 结论
结论
当前 Sink 的实现关键词是“单模块承接全部输出职责”:sink_v1 统一管理文件输出、设备输出和设备输出场景下的日志录制。它和 Source 共享默认骨架,但在产品能力结构上明显更收敛,也更偏终端落地。