强化学习驱动的和弦走向推导:基于旋律线预测二五一和弦替代走向
在爵士乐、City-Pop 以及现代流行编曲中,二五一(II - V - I)和弦走向是构建音乐张力与解决(Tension and Release)的最核心骨架。以 C 大调为例,最基础的走向是Dm7 -> G7 -> Cmaj7。
然而,如果 AI 编曲系统仅仅机械地在副歌和主歌套用标准二五一,整首歌听起来就会如同百货商场的廉价电梯音乐。真正赋予音乐高级感和戏剧性色彩的,是顶尖乐手在即兴演奏中信手拈来的和弦替代(Chord Substitutions):
- 三全音替代(Tritone Substitution):用降 II 级的
Db7替代属和弦G7,利用两者共享三全音(F 与 B/Cb)的物理特性,在低音声部造就平滑的半音阶下行(D -> Db -> C)。 - 降二副属扩展(Secondary Dominant Chains):插入
A7(b9)引向Dm7,构建连续的属和弦推动力。 - 调式借用与中音替代(Modal Interchange):引入同主音小调的降 VI 级和降 VII 级和弦,带来突然的离调阴郁感。
传统的马尔可夫链(Markov Chain)或纯自回归生成模型在处理替代和弦时存在一个致命死穴:它们容易在“安全但平庸的常规模板”与“突兀离调导致严重旋律打架(Avoid Notes 碰撞)”之间极端摇摆。
引入强化学习(Reinforcement Learning)与和声动力学评分,可以让模型在遵循旋律音引导的前提下,自主探索最优的张力替代走向。
强化学习环境建模:状态、动作与奖励函数
我们将和弦编排任务建模为一个马尔可夫决策过程(MDP):
[旋律线时序输入 Melody Notes] │ ▼ [当前环境状态 State(t)] - 当前旋律音与所在小节拍位 - 前驱和弦功能 (Tonic / Sub-Dominant / Dominant) - 低音当前音高 (Bass Register) │ ▼ [动作空间 Action Set: 候选和弦集合] - 标准二级 (Dm7, Dm7b5) - 属和弦族 (G7, G7alt, Db7 三全音替代) - 解决和弦 (Cmaj7, C6, Am7) │ ▼ [多维度奖励机制 Reward Function] ├── 声学张力与协和度 R_harm (旋律音与和弦内音的泛音重合度) ├── 声部平滑导向 R_lead (低音步进与内声部半音迁移距离) └── 惊喜度与新颖度 R_novelty (打破单调常规模板的探索奖励)1. 声学协和度与避用音惩罚($R_{\text{harm}}$)
当旋律音落在和弦外音时,必须严格区分是具有丰富色彩的可用延伸音(Available Tensions:如 9、#11、13),还是会产生泥泞碰撞的绝对避用音(Avoid Notes:如自然大调大七和弦上的纯四度音 F)。对于包含避用音的和弦动作,施加极大的负奖励。
2. 声部平滑导向奖励($R_{\text{lead}}$)
优秀的低音线条(Bassline)和内声部导向(Voice Leading)应该保持经济平滑。如果低音能够走出平滑的半音下行(例如 $D \to D\flat \to C$),系统给予极高的正向激励;相反,低音声部无规律的大跳跃(如增四度、大七度乱跳)则被抑制。
和声推导核心工程实现
以下是基于 TypeScript 实现的强化学习和弦走向预测与替代引擎:
export type PitchClass = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11; // 0=C, 1=C#, 2=D, 3=D#, 4=E, 5=F, 6=F#, 7=G, 8=G#, 9=A, 10=A#, 11=B export interface ChordCandidate { name: string; root: PitchClass; bassPitch: number; // 绝对低音音高 intervals: number[]; // 相对根音的半音间距 functionType: 'subdominant' | 'dominant' | 'tonic'; } export interface MelodyNote { pitch: PitchClass; octave: number; beatStrength: number; // 拍子强弱度 0.0 ~ 1.0 (正拍为 1.0,反拍弱) } export class HarmonicReinforcementEngine { // Q-Table 映射: `stateKey -> Map<chordName, qValue>` private qTable: Map<string, Map<string, number>> = new Map(); private learningRate = 0.15; private discountFactor = 0.85; /** * 计算候选和弦对当前旋律音的协和度与张力评分 */ public evaluateHarmonicReward(melody: MelodyNote, chord: ChordCandidate): number { const chordPitches = chord.intervals.map(interval => (chord.root + interval) % 12); const intervalFromRoot = (melody.pitch - chord.root + 12) % 12; // 1. 旋律音是和弦内音 (根音、三音、五音、七音) if (chordPitches.includes(melody.pitch)) { return 1.2; // 极佳的稳定度 } // 2. 旋律音是合法色彩张力音 (Tensions: 9, #11, 13) const validTensions = [2, 6, 9]; // 对应大九音、升十一音、十三音 if (validTensions.includes(intervalFromRoot)) { return 1.8; // 爵士乐推崇的高级色彩奖励 } // 3. 触发大调一级的避用音 (Avoid Note: 如大三和弦上的纯四度音) if (chord.functionType === 'tonic' && intervalFromRoot === 5) { return -2.5; // 严厉扣分,消除和弦三音与旋律小二度碰撞 } // 其它外音轻微扣分 return -0.4; } /** * 声部导向平滑度评分:鼓励低音半音阶下行 */ public evaluateVoiceLeadingReward(prevChord: ChordCandidate | null, currentChord: ChordCandidate): number { if (!prevChord) return 0.5; const bassInterval = Math.abs(currentChord.bassPitch - prevChord.bassPitch); // 半音级进(如三全音替代 Db -> C),给予最高奖赏 if (bassInterval === 1) { return 2.0; } // 纯四度向上或纯五度向下(标准五度圈跳进,如 D -> G -> C) if (bassInterval === 5 || bassInterval === 7) { return 1.5; } // 大跳(> 8 个半音)破坏低音稳定感,适度惩罚 if (bassInterval > 8) { return -1.0; } return 0.2; } /** * 基于旋律序列为 II-V-I 寻找最优替代走向 */ public predictSubstitutions( melodyTrack: MelodyNote[], candidates: ChordCandidate[] ): ChordCandidate[] { const chosenProgression: ChordCandidate[] = []; let prevChord: ChordCandidate | null = null; for (let step = 0; step < melodyTrack.length; step++) { const note = melodyTrack[step]; const stateKey = `step_${step}_mel_${note.pitch}`; if (!this.qTable.has(stateKey)) { this.qTable.set(stateKey, new Map()); } const actions = this.qTable.get(stateKey)!; // 寻找当前状态下 Q 值最高的候选和弦 let bestCandidate = candidates[0]; let maxScore = -Infinity; for (const candidate of candidates) { const currentQ = actions.get(candidate.name) || 0.5; // 计算即时环境反馈 const harmReward = this.evaluateHarmonicReward(note, candidate); const leadReward = this.evaluateVoiceLeadingReward(prevChord, candidate); // 综合得分 = Q值预测 + 即时物理声学奖励 const compositeScore = currentQ + harmReward * 1.5 + leadReward * 1.2; if (compositeScore > maxScore) { maxScore = compositeScore; bestCandidate = candidate; } } // 执行动作并更新 Q-Table const finalReward = this.evaluateHarmonicReward(note, bestCandidate) + this.evaluateVoiceLeadingReward(prevChord, bestCandidate); const oldQ = actions.get(bestCandidate.name) || 0.5; const updatedQ = oldQ + this.learningRate * (finalReward - oldQ); actions.set(bestCandidate.name, updatedQ); chosenProgression.push(bestCandidate); prevChord = bestCandidate; } return chosenProgression; } }替代走向演化实测与听感分析
以 C 大调旋律小节[E5, Eb5, D5, C5]为测试输入,将引擎放置于含有标准二五一和三全音替代和弦库中进行推导:
- 传统刚性匹配输出:
Dm7 (D-F-A-C) -> G7 (G-B-D-F) -> Cmaj7 (C-E-G-B)
听感:标准但寡淡,低音是常规的D -> G -> C,在第二拍处G7与旋律的Eb5(增五度/小十三度)缺乏合理的调式色彩铺垫。 - 强化学习替代引擎输出:
Dm7 -> Db7(#11) -> Cmaj7 -> C6
听感:当旋律走到Eb5时,系统自动识别出Eb与Db7构成大九度张力音(9th),并触发了平滑半音低音步进奖励。原本跳跃的低音线被重构为极其醇厚的D -> Db -> C爵士下行,低音贝斯的滑弦感瞬间被激活。
落地考量与算法边界
- 避免过度离调导致调性解体:
强化学习模型如果将“新颖度奖励”设置得过高,智能体会倾向于连续使用极端增减和弦与三全音替代,导致旋律完全失去大调明朗的归宿感。在工程落地时,必须在解决小节(Tonic Resolving Step)施加强约束,强制锁定一级的落地稳定性。 - 多声部吉他与贝斯的物理可演奏性(Playability):
算法输出的和弦走向不能脱离真实乐器的指板物理结构。一个在理论上完美的和弦代用,如果在贝斯或吉他上需要跨越六个品格的反人类反关节指法,在实际配器中就无法落地。在候选池阶段引入指板跨度几何惩罚,是确保 AI 编排能被真实乐手演奏的前提。