XHS · Hum to Symphony

made by Shingyui (Roy) He

哼一段旋律。
得到一首交响。

从 20 秒的自由哼唱,到 90 小节、结构完整的管弦乐曲——
和声由动态规划在 neo-Riemannian 空间中求解,而不是随手预测。

收听成品 在线体验和声规划
0.018Target MAE
100%段尾/终端命中
24三和弦 PLR 状态空间
90小节完整曲式

项目信息

一条从哼唱到交响乐的
符号化流水线。

XHS 不依赖端到端的黑箱生成。它把任务分解为可解释、可控制、可验证的五级管线:转录、和声规划、旋律展开、配器、渲染——每一级的输出都是可读可审的符号中间体(MIDI / 和弦计划 / 曲式标记)。

01

哼唱转录

basic-pitch 音频转 MIDI,保守清洗:孤立颤音滤波、调式估计与置信度、可选音阶与节奏网格吸附。

→
02

和声规划

NRT-DP 在 PLR 图上按段落 remoteness 剖面做边界感知动态规划,精确命中每个段尾与终端回归。

→
03

旋律展开

theme-and-variations 引擎:A/A′/A2 段保真再现用户主题,B/Dev 段模进、分裂、推向高潮。

→
04

管弦配器

AccoMontage-3(NeurIPS 2024)以主旋律 + 和弦计划 + 段落标记为条件,生成多轨管弦乐 MIDI。

→
05

渲染输出

FluidSynth + FluidR3 采样渲染为音频;段落力度弧线与旋律突出后处理保证层次。

用户认得出

主题的音高与节奏在呈示段逐音保留(实测与原旋律 index 对齐同 pitch-class 率 97.7%–100%),再现段完整回归——你哼的就是你听到的。

和声有设计

Intro 平静、B 段出走、Dev 段抵达最远张力、Coda 回家——整条张力曲线由目标剖面显式指定,由 DP 精确实现。

全程可复现

规划器纯标准库实现、确定性输出;每个中间产物(chords_by_bar、段落标记、旋律 MIDI)都可独立检查和替换。

技术内核

NRT-DP:在 neo-Riemannian 空间做规划的额定算法。阅读完整论文 ↗

24 个大小三和弦构成状态空间,相邻和弦之间只允许三种"俭约"变换——P(平行)、L(导音互换)、R(关系大小调)——外加保持(HOLD)。一个和弦相对主和弦的最短路径长度定义为它的 结构性 remoteness。

给定主调、各段长度、各段目标平均 remoteness 剖面 τ、段尾目标集与终端回归条件,规划器以 (前前和弦, 当前和弦, 累积 remoteness) 为状态做动态规划,按字典序优化三层目标:段均误差 J₁、段尾窗口逼近 J₂、HOLD/ABA 正则 J₃(λ = 0.15 / 0.60)。段间通过边界感知初始化保持整条轨迹连续。

精确期限可行性 Fr(C) 在每一步剪枝:任何无法在第 L 小节恰好落入段尾目标集的部分路径都不会进入搜索。段长 ≥ 6 时序贯规划可证不会失可行(直径 D = 5)。

实测(90 小节 XHS 曲式)

指标贪心启发式NRT-DP
Target MAE ↓0.3660.018
Contrast MAE ↓0.2880.036
最大相邻距离2(有违规)1(严格合法)
段尾命中率0.86–1.001.00
终端回归✓✓

旋律感知扩展:规划目标中加入 b9 避让 / 覆盖代价,让和声主动贴合用户旋律音——呈现小节的旋律音覆盖率从 0.24 提升到 0.63,规划指标无损。

代码

核心代码,直接看。

三段真实代码:额定算法 NRT-DP 的规划器核心、旋律引擎的唯一音高规则,以及正在本页运行的 JS 版规划器(点上面的标签切换)。

试听

从一段哼唱开始。

一段 23 秒的原创自由哼唱(F 大调)走过的完整链路。

① 哼唱输入

转录清洗后的用户主题(Voice Oohs 音色)

② 主题 + 和声骨架

theme-and-variations 旋律 × NRT-DP 和声 pad

③ 成品 · 编制 A

AccoMontage-3 配器:弦乐 / 圆号 / 钢琴 / 贝斯

④ 成品 · 编制 B

同一旋律与和声,另一组乐器配置

在线体验

亲手驱动 NRT-DP。

这是论文额定算法的完整 JavaScript 移植,在你的浏览器里实时运行——选一个主调和张力剖面,观察 90 小节和声骨架如何被动态规划求出,并直接试听。

选择参数后点击"规划和声"。
邻近主和弦 (remoteness 0) 中等张力 (2–3) 远离主和弦 (5)