brainstate

dourgey/BandBuddy · source

Snapshot 0 · 2026-11-04T12:47:28Z · TypeScript · Apache-2.0

Content fingerprint95c5f75478c0c9bccde77632ca25d7d5950a62198dec8f924547827aa859fe71

GitHub description at capture

A local-first Windows practice workstation with six-stem separation, A-B looping, tempo control, and metronome.

README at capture

<div align="center">
  <img src="./build/icon.png" width="112" alt="BandBuddy 图标">
  <h1>BandBuddy</h1>
  <p><strong>分轨练歌、系统学习、调音色与录音,一起留在本机。</strong></p>
  <p>面向乐手的本地优先桌面练琴工作台 · Local-first practice workstation for musicians.</p>
  <p>
    <a href="https://github.com/dourgey/BandBuddy/releases/latest"><img src="https://img.shields.io/github/v/release/dourgey/BandBuddy?display_name=tag&sort=semver" alt="Latest release"></a>
    <a href="https://github.com/dourgey/BandBuddy/actions/workflows/windows.yml"><img src="https://github.com/dourgey/BandBuddy/actions/workflows/windows.yml/badge.svg" alt="Windows CI"></a>
    <a href="https://github.com/dourgey/BandBuddy/actions/workflows/macos.yml"><img src="https://github.com/dourgey/BandBuddy/actions/workflows/macos.yml/badge.svg" alt="macOS CI"></a>
    <a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-c89b52" alt="Apache License 2.0"></a>
    <img src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS-357ec7" alt="Windows and macOS">
  </p>
</div>

BandBuddy 的核心不是“把人声去掉”,而是让一首歌真正变得**可练**:听清目标声部、放慢困难小节、循环到肌肉记住、跟着准确节拍进入,再在下一次打开时从原来的位置继续。

> [项目主页](https://bandbuddy.lonelyme.cn/) · [下载已发布版本](https://github.com/dourgey/BandBuddy/releases/latest) · [隐私说明](https://bandbuddy.lonelyme.cn/privacy.html) · 当前源码版本 `3.0.0` · Windows x64 / macOS Apple Silicon

本文对应当前源码;GitHub Release 的版本与安装文件以发布页为准。主要入口包括曲库与练习室、排练、练功房和军火库。

## 从听歌到练琴

```mermaid
flowchart LR
  A["导入歌曲"] --> B["先生成六轨,再补齐三条吉他细分轨"]
  B --> C["听清:Mute / Solo / 增益"]
  C --> D["拆练:变速 / 升降调 / A–B 循环"]
  D --> E["练准:BPM / 节拍器 / 预备拍"]
  E --> F["录下:多轨 Take / 整场排练"]
  F --> G["自动保存,下次继续"]
  G --> H["导出分轨或练习混音"]
```

BandBuddy 把一次有效练习整理成一条很短的路径:**选歌 → 分轨 → 聚焦 → 慢练 → 循环 → 合奏**。账号、云曲库和联网播放器都不是这条路径的前提;音乐、模型、练习状态和导出结果都留在你的电脑上。

## 界面

![BandBuddy 曲库:最近练习、歌曲状态与分轨信息](./docs/images/library.png)

曲库会记住最近练过什么、练到哪里,并把分轨任务状态、收藏和搜索放在同一个入口。截图使用演示数据,项目不附带其中的音乐。

![BandBuddy 练习室:同步波形与底部练习控制](./docs/images/practice-room.png)

练习室让已生成的分轨共用一条播放时钟和同一段 A–B 区间。HTDemucs 六轨完成后歌曲就能开始练习,三条吉他细分轨会在后台继续生成;期间“吉他分轨”按钮会显示等待说明,完成后在按钮旁即时通知。打开该模式时,原 Guitar 自动静音并隐藏,切换为 Acoustic、Lead、Rhythm 三轨。所有调整都会自动保存。

## 为练琴准备的功能

### AI 图文对话

- 点击界面右下方的悬浮 AI 图标打开对话窗口,可收起后继续操作软件。支持新建、切换、重命名、删除会话,以及停止和重试回复。
- 图片可通过选择文件、粘贴或拖入添加,支持 PNG、JPEG、WebP、GIF;每条消息最多 4 张,单张不超过 5 MB、合计不超过 12 MB。图片随消息保存,重启后可继续查看。
- 可直接打开 AI 对话。在「设置 → 实验室功能 → AI 对话」填写自己的 Base URL、Token / API Key 和模型名后,点击「检验配置」,通过后自动保存并启用;也可先保存表单稍后检验。支持 OpenAI Chat Completions 兼容接口,仅开放这三个配置,其他参数固定使用软件默认值(流式回复、120 秒超时、图片细节自动,生成参数使用服务商默认值)。旧版保存的高级参数自动恢复为默认值。
- 上下文最多 20 轮(含本次提问);达到 20 轮或上下文文字(含已有摘要)超过 32768 字符时,自动将较早对话压缩成摘要并保留近期对话。摘要和压缩位置保存在本机,重启后继续使用;完整历史不受压缩影响。压缩失败或取消时保留完整历史,可重试。
- AI 音乐小伙伴「邦邦」会通过当前模型接口识别问题意图:软件功能与操作问题参考随应用打包的指南;当前设置、音频设备、分轨任务和报错问题按需读取脱敏信息;其他问题直接回答。状态查询只读,不修改配置、执行命令或打开麦克风。指南源文件为 `resources/ai-assistant-guide.json`。
- 邦邦喜欢音乐,语气俏皮亲切,不介绍后台模型身份。密钥不放入参考资料,流式回复与保存内容另有密钥过滤。生成参数使用服务商默认值。图片理解能力由所选模型提供。发送时,会将上下文文字、图片及必要的指南或脱敏状态提交到配置的接口;连接检验会发送一条简短测试消息。
- 会话与图片保存在应用用户目录的独立 `ai-chat.db` 中,首次使用时才打开数据库;Token 通过 Electron `safeStorage` 加密保存,不会返回到普通设置对象或写入聊天诊断日志。中断回复会保留已收到的内容,并可在重启后重试。
- 源码不包含共享 API Key。自行构建默认通过上述设置配置接口;如需使用源码中的默认服务,可在启动主进程前设置 `BANDBUDDY_AI_TOKEN` 环境变量。未提供凭据时会提示配置,不发送默认服务请求。

### 军火库:搭建音色、监听与快录

![军火库工作台](./docs/qa/images/arsenal-workstation-720.png)

- 从八个原生起始音色开始,或搭建最多 24 个模块的效果链;支持重复模块、拖动排序、复制、旁通和删除。
- 使用箱头、箱体、动态、均衡、调制、延迟与混响,并可导入自己的 NAM 模型和 IR。资源逐文件校验,支持名称、标签和备注管理。
- 保留工作台草稿,支持撤销/重做、会话内 A/B 快照、用户预设、收藏、搜索和 `.bbtone` 导入导出。预设文件包含参数与资源哈希,NAM / IR 文件需另行导入。
- 原生监听可跨页面保持,全局状态条支持返回或停止;重新启动应用不会自动开启输入。调音器使用同一原生输入,调音时静音效果声,伴奏仍可播放。
- 快录保存原始 DI 和开始录制时的音色快照;可选择最长 60 秒片段循环调音,导出 DI 或用当前音色导出效果声。
- 监听开启时,练习伴奏可以与输入共用原生立体声输出。设备面板显示真实输入/输出电平、驱动与 DSP 报告延迟、处理负载和中断次数。

操作与验证范围见[军火库工作台验收记录](./docs/qa/arsenal-workstation-2026-10-05.md)。原生练习室预览、本机 VST3 / Audio Unit 插件与录音保护的使用入口和验收边界见[原生音频与本机效果插件](./docs/audio-engine-upgrade.md);NAM A2 的参考插件对照见[NAM A2 数值对照](./docs/nam2-plugin-parity.md)。

### 练功房:从知识到专项练习

- 按“体系卡片 → 路线图 → 知识正文”学习,教材、图解和谱例随应用打包,可离线阅读。
- 覆盖十个知识体系,提供电吉他、原声吉他、贝斯、尤克里里、鼓、钢琴与键盘的乐器情境;文章包含学习目标、步骤、例子、常见问题和自检。
- 合成器体系包含 9 个阶段、36 课,涵盖减法、FM、波表、加法、采样、颗粒与模块化等内容,操作实验供读者在自己的软硬件合成器中完成。
- 专项练习与合奏练习使用统一 MusicXML 阅读器呈现五线谱、TAB、打击乐谱和钢琴大谱表,并支持播放高亮与谱面内部滚动。
- 指板实验室用于探索音阶与和弦;工具箱提供节拍器、调音器、鼓机、和弦查询、五度圈与持续参考音。

教材目录与维护方法见[练功房教材说明](./resources/learning/README.md)。

### 听清每一个声部

- 分轨分成两个持久化阶段:先生成 `Vocal / Drums / Bass / Guitar / Piano / Other` 六轨并开放练习室,再在后台补齐 `Acoustic / Lead / Rhythm`。
- 原六轨模式和吉他细分模式即时切换;隐藏备选轨不参与 Solo、独立输出、快捷键选择或默认混音导出。
- 练习室的「人声分轨」与「吉他分轨」一样是切换按钮:点击开启后显示主唱、和声两轨,再次点击恢复完整人声。尚未生成时按需细分已保存的人声,期间继续使用完整人声,完成后自动开启;后台自动生成只提示就绪。人声音轨菜单保留「去主唱,保留和声」「仅听和声」,播放中切换采用预载和淡化。
- 新歌曲在基础分轨完成后自动细分主唱与和声,期间即可使用基础分轨练习;细分完成后提示就绪,通过练习室「人声分轨」按钮切换。首次使用按需下载模型,沿用全局 FLAC 24 位/MP3 320 kbps 保存选项;模型失败、取消或重试均保留基础分轨。局域网网页支持同一组切换,旧 v1 客户端仍获取完整人声。
- 设置中的「人声分轨档位」提供效率档(Mel-Band RoFormer,aufr33 / viperx)和质量档(BS-RoFormer,frazer / becruily),默认效率档。手动及自动细分均使用所选档位,已排队任务保留创建时的模型。两套模型从 [ModelScope `BandBuddy-Models`](https://modelscope.cn/models/Zzzzzzorz/BandBuddy-Models) 的固定 `vocal-v1.0` 标签按需下载,由 `resources/vocal-model-catalog.json` 固定文件大小、版本与哈希;`scripts/verify-vocal-split.py` 可对已保存人声批量做两模型推理和编码校验。
- 当前模式的同步波形可独立 `Mute`、`Solo` 和调节增益,另有主音量控制。
- 选择多通道输出设备后,每条分轨可独立路由到 `1–2 / 3–4 / …` 立体声通道对,便于通过 Loopback 等虚拟声卡送入 DAW。
- macOS 下选择 Loopback 时会自动修复其全部为“未知”的声道标签,避免 8 路设备被识别为 2 路;保留已配置的声道布局。单声道素材在所选立体声通道对中居中播放。
- Piano 是实验性声部;复杂编曲里可能与 Guitar 或 Other 串音,界面会持续提示这一点。

### 把难点缩小,反复练会

- 在波形上选择区间,或连续点击同一个 A–B 按钮:第一次设置 A,第二次设置 B 并立即开始循环,第三次取消。按钮会显示等待 B 点和循环中的不同状态,循环边界会随歌曲保存。
- 点击“跳回并播放”可立即重练:循环启用时跳回 A 点,否则跳回歌曲开头;暂停时也会直接开始播放,不重复预备拍。
- 提供 `0.5× / 0.8× / 1.0× / 1.2× / 1.5×` 快捷速度,以及 `0.20×–4.00×` 无级变速,播放时保持音高。
- 底部播放栏可直接点 `♭ / ♯` 降低或升高 1 个半音,范围为 `-12–+12`(上下各一个八度),并可一键恢复原调;点击调值可打开滑轨。使用 Signalsmith Stretch 实时统一调整人声、贝斯、吉他、钢琴及其他分轨,鼓轨保持原音并自动补偿延迟,播放速度不变。
- 已生成轨由同一主时钟校正;后台补齐吉他三轨时会无中断接入当前歌曲,之后的变速、跳转、循环和模式切换仍保持同步。
- 播放位置、速度、升降调、循环、每轨 Mute/Solo/增益/输出通道对、缩放与滚动视图都会自动保存。

### 看着视频一起练

- 支持导入 `MP4 / M4V / MOV / MKV / WebM / AVI`。后台先提取音频,再交给本地分轨;原视频文件会保留在受管曲库中。
- 视频歌曲在练习室显示视频画面和当前模式的混音控制,替代波形视图;纯音频歌曲使用同步波形。
- 画面跟随分轨的播放、暂停、跳转、A–B 循环和 `0.20×–4.00×` 速度变化,原视频音轨静音,避免与分轨重复发声。
- 支持按钮或双击画面进入全屏;全屏内可控制播放、进度、速度、循环和跳回重练。
- 视频必须包含音轨。不兼容的画面编码会在本机转换为可播放副本,处理时间和额外磁盘占用取决于视频长度与分辨率。

### 跟上节拍再进入

- 可优先分析鼓轨自动检测 BPM,也可以手动修改。
- 可在本机识别歌曲主调与大小调,显示置信度;低置信度时给出前三候选,并按片段提示可能转调的位置。识别结果支持手动纠正,重新分析不会覆盖手动选择。
- 内置节拍器支持拍点提前/延后微调,并随播放速度同步。
- 支持关闭、4 拍或 8 拍预备拍,让手和乐器先准备好再进入歌曲。

### 录下练习并比较 Take

- 在练习室创建多条录音轨,从任意播放位置开始录制;每条轨可保留多个 Take,并独立选择、命名、Mute、Solo 和调节增益。
- 支持 Windows WASAPI、macOS CoreAudio,以及系统可用时的 ASIO;可以选择输入/输出设备、单声道或立体声通道、采样率与 Buffer,并先做输入电平测试。
- 预备拍不会写入 Take;可按设备保存对齐偏移,分离输入/输出设备时会做时钟校正并显示 xrun 计数。
- 导出当前练习混音时,可以把所有启用的录音轨一起混入,并保持录制时的练习速度、调性与位置关系。

### 编排和录制整场排练

- 创建多份排练编排单,把曲库歌曲和可调时长的空白衔接拖入队列并重新排序。
- 按每首歌保存的速度、预备拍、节拍器与混音状态连续播放整条时间线,也可以随时进入单曲练习后返回原排练位置。
- 为整场排练建立多条录音轨,从当前时间线位置连续叠录、暂停或继续;每个 Take 绑定当时的编排修订,后续改动不会让旧录音失去上下文。

### 跟着时间轴歌词练习

- 为歌曲导入或替换标准 `.lrc` 时间轴歌词。
- 在独立的置顶桌面歌词窗口显示当前句、下一句和歌曲进度;排练连续播放时会随当前歌曲自动切换。

### 管理自己的练习曲库

- 导入音频 `MP3 / WAV / FLAC / M4A / AAC / OGG / OGA / OPUS / AIF / AIFF / WMA / M4B / APE / WV / MP2 / AC3 / CAF`,并兼容用户有权使用的本地 `.ncm` 文件。
- 导入带音轨的视频 `MP4 / M4V / MOV / MKV / WebM / AVI / WMV / FLV / MPG / MPEG / TS / MTS / M2TS / VOB / 3GP / 3G2 / OGV / ASF`;具体编码须受内置 FFmpeg 支持,不支持 DRM 加密媒体。
- 基础分轨和吉他细分均先用 FFmpeg 解码为 44.1 kHz 双声道浮点 WAV,保留原文件;视频额外保留音画时间对齐。
- 搜索歌曲或艺术家,按收藏、处理中、最近练习筛选,并在列表/卡片布局间切换。
- 后台任务展示分轨和导出进度;支持取消、重试,以及显存不足后使用相同质量参数的 CPU 重试。
- 可从曲库或练习室编辑标题、艺术家、BPM、歌曲调与拍号;歌曲调既可本地识别,也可手动纠正。
- 启动时会核对已保存的播放与录音设备;明确选择的设备与 ASIO 配置会保留,设备异常时停止受影响的监听,不会恢复后自动换用另一支麦克风或扬声器。
- 设置中的 Debug 模式切换后立即生效,会把 renderer、preload、IPC 与进程异常写入 `debug.log`;设置页可直接在文件管理器中定位该文件,代理凭据、令牌和密码会先脱敏。
- 删除的受管歌曲会先进入系统废纸篓 / 回收站。

### 带走分轨或当前练习混音

- 分别导出所选标准分轨,或导出应用了 Mute、Solo、每轨增益与主增益的当前混音。
- 导出会自动保留当前 Signalsmith 升降调:所有非鼓轨变调,鼓轨保持原音;当前混音还可选择应用练习速度、只导出 A–B 区间,并在输出前限制峰值避免削波。
- 支持 `WAV / FLAC`(44.1 kHz、24-bit)和 `MP3`(320 kbps)。

### 局域网练琴与移动端同步

在设置中开启「局域网模式」,即可用同一网络的手机、iPad 或电脑访问设置页显示的地址,独立播放曲库中已完成分轨的歌曲。支持播放/暂停、AB 循环、±12 半音升降调、音轨浮窗中的音量/M/S、歌词与视频。默认使用 60232 端口,冲突时自动选择空闲端口。关闭模式或退出 App 后访问地址失效。

桌面端还提供 UDP/HTTP 发现、移动客户端握手、歌曲 manifest、带 SHA-256 校验的分轨和视频下载,以及 Range 断点续传。详见 [移动端同步协议 v1](docs/lan-sync-api.md)。

导入窗口恢复「已分轨数据」入口,支持 2–9 条已有音轨、预设或自定义轨道名称,直接进入标准化队列,无需安装分离模型。

## 常用快捷键

以下快捷键用于歌曲练习室。

| 按键 | 操作 |
| --- | --- |
| `Space` | 播放 / 暂停 |
| `←` / `→` | 后退 / 前进 5 秒;按住 `Shift` 时为 1 秒 |
| `↑` / `↓` | 选择上一条 / 下一条音轨 |
| `M` / `S` | 切换当前音轨的 Mute / Solo |
| `+` / `-` / `0` | 当前音轨增益 +1 dB / -1 dB / 归零 |
| `L` | 依次设置 A、设置 B 并开始循环、取消循环 |
| `A` / `B` | 重新设置 A 点 / 设置 B 点并开始循环 |
| `Home` | 跳回 A 点(循环中)或歌曲开头,并继续播放 |
| `Esc` | 全屏时退出全屏;其他时候清除循环区间 |

## 本地优先

- **无需上传音乐**:分轨、波形、BPM 与歌曲调检测、混音和导出全部在本机完成。
- **独立运行环境**:应用安装私有 CPython、PyTorch 和 Demucs,不读取系统 Python、PATH 或注册表 Python。
- **按设备自动回退**:Windows 优先使用可用的 NVIDIA CUDA,macOS 优先使用 Apple MPS;不可用、设备失效或显存不足时可回退 CPU。
- **可验证的依赖**:uv、FFmpeg 和模型按固定版本下载并校验 SHA-256;代理凭据会从日志中脱敏。
- **可恢复的数据操作**:SQLite 使用 WAL 和迁移备份;重新分轨成功前保留旧版本,删除音乐时先移动到回收站。

曲库首次显示后,应用会在后台检查并准备所需组件;录音或原生监听期间推迟准备。可在“设置 → 运行状态”查看各功能状态、下载进度,暂停、继续、一键修复或导出本地诊断。主动暂停会跨启动保留。

分轨环境会下载私有 Python、Torch 和固定的四份权重。所需空间随 CPU / CUDA 后端及缓存变化,安装前会检查各目标磁盘的可写性与峰值空间。Python、wheel 与模型支持缓存、续传及完整性校验;候选环境通过依赖导入、ONNX CPU 运算和六轨短推理后才启用,修复失败保留此前可用环境。

连续启动失败时会进入兼容启动,暂停后台准备与自动原生设备枚举;数据库异常时提供恢复入口,由用户选择备份。详见[环境准备与恢复说明](./docs/runtime-robustness.md)。

设置中的“高音质分轨”决定新任务两个阶段的最终存储格式:关闭时全部轨统一保存为 44.1 kHz、stereo、320 kbps MP3,开启时统一保存为 44.1 kHz、stereo、24-bit FLAC。吉他细分另有“极速 / 平衡 / 高质量”三个推理档位;存储格式开关不会改变所选推理档位,已有歌曲只有重新分轨后才会改变格式。

### 中国大陆与受限网络

应用默认启用“中国大陆镜像”环境源,也可以在“设置 → 高级网络 → 环境下载源”切换为官方源或逐项填写自定义 HTTPS 地址:

| 内容 | 大陆下载源 | 完整性与回退 |
| --- | --- | --- |
| 私有 CPython | npmmirror 的 `python-build-standalone` 镜像 | 平台清单固定版本、大小与 SHA-256;官方文件作为备选,下载可缓存续传 |
| Demucs 与常规 Python 包 | 清单中已核验的国内镜像及官方备选源 | 包含间接依赖的 wheel 固定版本、大小与 SHA-256;下载后从本地缓存安装 |
| PyTorch / Torchaudio | 固定 wheel 清单中的镜像与官方源 | Windows 提供 CPU、CUDA 12.8 / 13.0 清单;结合驱动、GPU 架构与真实运算测试选择后端 |
| 六份基础/吉他分轨权重 | [ModelScope `BandBuddy-Models`](https://modelscope.cn/models/Zzzzzzorz/BandBuddy-Models) 固定 `v2.0.1` 标签 | 固定文件路径、字节数与完整 SHA-256;全部验证后原子写入完成标记 |
| 两份主唱/和声细分权重 | 同仓库固定 `vocal-v1.0` 标签 | 按档位下载,校验固定字节数与完整 SHA-256;对应配置随应用附带 |

环境镜像不可用时,可先切换另一环境下载源再点“修复环境”;已完成的缓存和权重 `.part` 文件会继续使用。公司网络还可以选择系统代理或填写手动 HTTP(S) 代理。Python 包与桌面工具可切换镜像,权重下载地址和固定版本不可由用户修改,所有完整性校验始终开启。

## 安装 Windows 版

前往 [Releases](https://github.com/dourgey/BandBuddy/releases/latest),按需要下载:

- `BandBuddy-<版本>-x64.exe`:安装版,可选择安装位置并创建桌面/开始菜单快捷方式。
- `BandBuddy-<版本>-x64-portable.exe`:便携版,无需运行安装向导。
- `SHA256SUMS.txt`:用于校验下载文件完整性。

开源 CI 在没有 Authenticode 证书时会发布**未签名**构建,Windows SmartScreen 可能显示“未知发布者”。Release 说明会标明该版本是否已签名;如果你不接受未签名程序,可从源码构建,或等待 Microsoft Store / 已签名版本。

## 安装 macOS 版

[Releases](https://github.com/dourgey/BandBuddy/releases/latest) 提供 Apple Silicon 原生 `DMG` 和 `ZIP`:

- `BandBuddy-<版本>-macos-arm64.dmg` / `.zip`:Apple Silicon Mac。

签名、公证状态与校验文件以具体 Release 说明为准。应用基础功能的最低版本声明为 macOS 13;当前 Apple Silicon 本地分轨依赖清单要求 **macOS 14+**。

## 从源码运行

需要 Windows 10/11 x64 或 macOS Apple Silicon、Node.js 24+、pnpm 11+、CMake 3.24+ 与 C++20 编译器。Windows 可从微软的 [C++ Build Tools 指引](https://learn.microsoft.com/zh-cn/cpp/build/building-on-the-command-line?view=msvc-170) 安装 Visual Studio 2022,并勾选“使用 C++ 的桌面开发”和 CMake 工具;构建脚本会自动查找其自带的 `cmake.exe`,也可通过 `CMAKE_EXECUTABLE` 指定。macOS 使用 Xcode Command Line Tools。系统无需预装 Python、Torch、CUDA Toolkit 或 FFmpeg。

```powershell
git clone https://github.com/dourgey/BandBuddy.git
cd BandBuddy
pnpm install
pnpm tools:fetch
pnpm test
pnpm dev
```

`pnpm tools:fetch` 会下载并逐文件校验固定版本的 uv 与 FFmpeg。`pnpm dev` 会先构建原生音频宿主;Windows 下还会构建系统辅助程序并准备经过签名验证的微软运行库安装器,因此首次构建需要联网。只查看界面时可运行 `pnpm dev:renderer`,然后打开 `http://localhost:5173/?fixtures=1`;fixture 模式只在开发环境启用,不会进入正式构建。

中国大陆可使用下面的流程;镜像配置只对当前命令生效,不会改写用户的全局 `.npmrc`:

```powershell
# GitHub 无法直连时,可通过第三方代理克隆;有条件时仍优先使用上面的官方地址
git clone https://ghfast.top/https://github.com/dourgey/BandBuddy.git
cd BandBuddy

# 如果尚未安装 pnpm
npm install --global pnpm@11.9.0 --registry=https://registry.npmmirror.com

pnpm install:cn
pnpm tools:fetch:cn
pnpm test
pnpm dev:cn
```

`install:cn` 使用 npmmirror 获取 npm、Electron、electron-builder 和 `better-sqlite3` 的 Node 预构建文件;Electron ABI 没有对应预构建时,会使用前述 C++ 工具在本地重建。`tools:fetch:cn` 会依次尝试多个 GitHub 代理,原生音频依赖默认使用 `ghfast.top`;两者都保留断点或构建缓存,并在失败时尝试官方地址。所有固定桌面工具仍按 `resources/tool-manifest.json` 校验 SHA-256。若需要使用自建 GitHub 代理,可在运行前设置 `BANDBUDDY_GITHUB_PROXY`(其格式为可直接前置到完整 GitHub URL 的 HTTPS 前缀)。第三方代理不等同于 GitHub 官方服务,请结合可信渠道核对源码 commit。

### 构建 Windows 包

```powershell
pnpm package:dir       # 未签名的解包目录:release-unsigned/win-unpacked
pnpm package:unsigned  # 未签名安装版 + 便携版:release-unsigned
pnpm package           # 需要 Authenticode 证书的正式签名包:release
pnpm package:store     # Microsoft Store AppX:release-store
```

签名构建通过 `WIN_CSC_LINK` 与 `WIN_CSC_KEY_PASSWORD` 向 electron-builder 提供 PFX/P12 证书。`pnpm package` 会在证书缺失、签名无效或任一 `.exe/.dll/.node` 未签名时失败。

### 构建 macOS 包

```bash
pnpm package:mac:dir        # 强制 Developer ID 签名并验证 .app
pnpm package:mac            # 强制签名、验证 DMG + ZIP:release-macos
pnpm package:mac:notarized  # 签名 + Apple 公证 + 票据及 Gatekeeper 验证
pnpm verify:mac:signatures  # 重新验证 release-macos 的签名、安装包与独立启动
pnpm package:mac:unsigned   # 仅供无证书 CI / 开发测试:release-macos-unsigned
pnpm package:mac:x64        # Intel 原生构建;依赖发布门禁未完成时明确阻止
pnpm package:mac:x64:unsigned  # Intel CI 测试包,同样需要通过依赖门禁
```

默认构建 Apple Silicon(arm64)包;Intel 命令包含 `:x64`,也提供 `:dir` / `:notarized` 变体。必须在对应架构的原生 Mac 上构建,以便 Electron、`better-sqlite3`、uv 和 FFmpeg 保持同一架构。发布校验逐一检查 Mach-O 架构和最低部署版本(macOS 13)。

Intel 分轨依赖目前尚未完成原生发布验收,不能仅根据构建脚本宣称已支持。先手动运行 [Intel runtime wheel workflow](./.github/workflows/runtime-wheel-macos-x64.yml):从固定 SHA-256 的 sphn 0.1.12 官方源码构建 CPython 3.12 / macOS 13 x64 wheel,静态链接 Opus;所有传递依赖准备为 wheel,并在 Intel CPU 上验证中文路径音频往返、真实 ONNX 推理、六轨分离及 fast / balanced / high 吉他分离。该任务仅上传供审查的 CI 产物,不自动发布。

原生验收还必须与已审查 CPU 参考逐轨比较,覆盖六轨和三个吉他质量档位的共 15 个输出;固定输入、种子、模型哈希、生产代码哈希、误差阈值及参考导出命令见[环境鲁棒性说明](./docs/runtime-robustness.md)。有限数值或正确形状不能代替输出比较。参考 pin 和真实波形包缺失时 CI 明确阻止验收。

审查通过后,将完整 wheelhouse 发布到固定版本的 GitHub Release,再提交产物中的 `resources/runtime-wheels.json`、`python/runtime/macos-x64.lock`、`python/runtime/macos-x64-validation.json`、`python/runtime/macos-x64-cpu-comparison.json` 以及已审查的 `python/runtime/cpu-reference.json`。当前清单为空,正式参考 pin 尚未提交;Intel 打包会明确失败,直到完整锁、匹配的原生及数值验证证据和全部线上 wheel 的哈希均通过校验。用户机器不会编译这些依赖。

签名是默认打包的必经步骤:使用钥匙串中团队 `M6M993UYR9` 的有效 Developer ID Application 证书,或通过 `CSC_LINK` / `CSC_KEY_PASSWORD` 提供该团队的 P12。脚本使用证书指纹,避免同名证书歧义;可用 `BANDBUDDY_MAC_SIGN_IDENTITY` 明确指定指纹。缺少证书、任何签名/校验失败都会终止构建,不自动降级为未签名包。

脚本按文件头扫描包内所有 Mach-O,包括主程序、Electron Helper / Framework / 动态库、crashpad、SQLite `.node`、uv、ffmpeg、ffprobe 和原生 audio-host,先签内部代码再签外层容器,启用安全时间戳和 Hardened Runtime。Python、JSON、语言资源等由 App 资源封印保护,不逐个当作可执行文件签名。新增内嵌原生依赖会自动纳入扫描与逐项验证。签名时遵循 [Apple 的嵌套代码签名流程](https://developer.apple.com/documentation/xcode/creating-distribution-signed-code-for-the-mac/)。

打包后自动检查 DMG 自身签名、DMG 镜像完整性、DMG/ZIP 内完整应用签名及发布者,并从独立临时目录启动解压后的应用,确认 FFmpeg 不依赖源码目录。按架构生成 `SIGNATURE-REPORT-macos-arm64.json` / `SIGNATURE-REPORT-macos-x64.json` 及对应的 `SHA256SUMS-macos-<arch>.txt`。构建前仍用上游固定 SHA-256 校验工具原件;运行时只有完整 App 的资源封印及指定发布者签名验证通过,才接受签名导致的内嵌工具哈希变化。

默认签名包不等同于 Apple 公证。`package:mac:notarized` 额外要求 `APPLE_KEYCHAIN_PROFILE`(可选 `APPLE_KEYCHAIN`),或 `APPLE_ID` / `APPLE_APP_SPECIFIC_PASSWORD` / `APPLE_TEAM_ID`,或 `APPLE_API_KEY` / `APPLE_API_KEY_ID` / `APPLE_API_ISSUER`。公证票据或 Gatekeeper 检查未通过,构建同样失败。安装时下载到用户数据目录的 Python 及依赖不属于 App 包内签名清单。

## CI 与 Release

- [Windows CI](./.github/workflows/windows.yml) 在 `main`、Pull Request 和手动运行时执行资源校验、类型检查、测试与未签名 Electron 打包,并保存构建产物。
- [macOS CI](./.github/workflows/macos.yml) 使用 Apple Silicon 与 Intel 原生 runner 运行源码测试。默认只生成 Apple Silicon 测试包;Intel 打包在仓库变量 `ENABLE_INTEL_MAC_RELEASE=true` 时启用,仍须通过全部依赖与数值验收门禁。
- [Release workflow](./.github/workflows/release.yml) 在推送与 `package.json` 版本一致的 `v*` 标签时,默认继续构建和发布 Windows x64、macOS arm64,并明确说明 Intel 尚待验收。完整提交并审查 Intel 证据后,设置仓库变量 `ENABLE_INTEL_MAC_RELEASE=true` 将 x64 纳入发行;此后必须三个平台及签名、依赖和 CPU 数值门禁全部通过才发布,Intel 失败不会静默退回双平台发行。
- macOS Release 必须配置 `MACOS_CSC_LINK` 和 `MACOS_CSC_KEY_PASSWORD`,强制执行签名与安装包验证;缺少凭据会失败,不再发布未签名 macOS Release。
- 如果仓库配置了 `WINDOWS_CSC_LINK` 和 `WINDOWS_CSC_KEY_PASSWORD`,Release workflow 会生成并验证签名包;否则会明确发布未签名社区构建。

## 项目结构

| 路径 | 职责 |
| --- | --- |
| `src/main` | Electron 主进程、SQLite、任务队列、导入/导出与安全边界 |
| `src/preload` | 经过约束的 renderer ↔ main IPC 桥 |
| `src/renderer` | React 曲库、练习室、练功房、军火库与播放器 |
| `native/audio-host` | RtAudio / PortAudio 原生录音宿主与设备时钟协议 |
| `native/effects` | 原生效果处理、NAM / IR 与模块化音色链 |
| `native/system-helper` | Windows 系统依赖检测、签名验证与授权安装辅助程序 |
| `resources/learning` | 离线教材、MusicXML 谱例与 SVG 图解 |
| `resources/runtime-catalog` | 各平台 Python 与完整 wheel 依赖清单 |
| `python/worker` | HTDemucs 六轨与吉他三轨两阶段工作进程、固定 ModelScope 权重清单及断点下载协议 |
| `python/msr_mvp` | 模型/轨数无关的 MSS → MSR 实验管线与适配器 |
| `python/guitar_separator_hq` | 生产使用的固定 HQ6 木吉他 / Lead / Rhythm 推理模块与独立审计工具 |
| `packages/shared` | 领域类型、Zod schema 与 IPC 合约 |
| `resources` / `scripts` | 固定桌面工具清单、下载和验证脚本 |
| `tests` | 音频规则、迁移、路径安全、任务状态和播放器测试 |

更详细的进程边界、数据原子性、音频管线和 worker 协议见 [架构说明](./docs/ARCHITECTURE.md);MSS → MSR 独立实验见 [MVP 说明](./python/msr_mvp/README.md) 和 [实测记录](./docs/experiments/msr-mvp-2026-08-25.md);吉他三轨逆向与最高音质实验见 [HQ6 说明](./python/guitar_separator_hq/README.md) 和 [完整报告](./docs/experiments/bd-guitar-separator-v14.5-hq6-2026-09-03.md)。第三方组件及许可见 [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md)。

## 当前边界

当前源码面向 Windows x64 与 macOS Apple Silicon;Intel Mac 仍受上文发布门禁约束。提供桌面端托管的局域网浏览器播放,不提供账号、云同步或自动更新。Piano 分轨仍为实验性功能。

军火库的设备模拟不代表对特定硬件的实测复刻;当前统一伴奏输出为立体声,不提供原生多硬件输出总线。自动测试与模拟声卡验证不能替代真实声卡的延迟、拔插、长时间稳定性和听感验收。干净 Windows、其他 GPU / 驱动及 Apple Silicon 最低支持系统仍需相应机器验收;本次源码更新不等于发布新安装包。

欢迎通过 [Issues](https://github.com/dourgey/BandBuddy/issues) 提交可复现的问题和练琴场景建议。

## 许可与音频权利

BandBuddy 源码使用 [Apache License 2.0](./LICENSE)。分轨运行时使用 Demucs 4.1.0 与固定的 MSST 架构代码;相应 MIT 许可和版权声明收录在 [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md)。四份权重不打入安装包,而是从公开的 [ModelScope 权重仓库](https://modelscope.cn/models/Zzzzzzorz/BandBuddy-Models) `v2.0.0` 分支下载;该仓库按 GPL-3.0 发布并保留来源与第三方声明。

其他第三方工具、库和模型保留各自许可。BandBuddy 不附带音乐;请只导入、处理和导出你拥有或已获授权使用的音频。

## 支持 BandBuddy

如果 BandBuddy 对你的练习有所帮助,并且你刚好有余力,欢迎请作者喝杯咖啡,支持项目继续维护和改进。赞助完全自愿,不会影响任何功能的使用。

如果希望在赞助名单中留名,请在付款时备注希望展示的名字或 GitHub 用户名;未备注的赞助将默认匿名。感谢你的支持!

<p align="center">
  <img src="./docs/images/wechat-pay.jpg" alt="微信收款码" width="280">
  <img src="./docs/images/alipay-pay.jpg" alt="支付宝收款码" width="280">
</p>