生成式音乐作曲 generative-music-composer

这个技能专注于使用算法和程序化方法自动或半自动生成音乐作品,涵盖马尔可夫链、L系统、神经方法等技术,适用于环境音乐、适应性音乐和实验音乐创作。关键词:算法作曲,生成音乐,马尔可夫链,L系统,神经音乐生成,程序化音乐,适应性音频。

编曲作曲 0 次安装 0 次浏览 更新于 3/7/2026

名称: 生成音乐作曲家 描述: 使用过程生成、马尔可夫链、L系统和神经方法创建算法音乐作曲系统,用于环境音乐、适应性音乐和实验音乐。 许可证: MIT

生成音乐作曲家

本技能提供指导,用于创建自主或半自主生成作品的算法和程序化音乐系统。

核心能力

  • 算法作曲:基于规则的音乐生成
  • 随机方法:马尔可夫链、概率分布
  • 形式文法:L系统、音乐生成文法
  • 适应性系统:响应输入/上下文
  • 神经方法:基于机器学习生成技术

生成音乐基础

生成范式

方法 描述 最佳用途
基于规则 明确的作曲规则 传统风格、受控输出
随机 概率驱动选择 自然变化、惊喜
基于文法 递归结构生成 复杂形式、自相似性
基于约束 满足音乐约束 和声、声部进行
基于学习 在语料库上训练 风格模仿、新颖性

生成音乐元素

┌─────────────────────────────────────────────────────────┐
│                    音乐生成层次                       │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  宏观结构    │ 形式、段落、调性区域                 │
│  ──────────────────────────────────────────────────────│
│  和声            │ 和弦进行、声部进行                 │
│  ──────────────────────────────────────────────────────│
│  旋律             │ 音高序列、轮廓、节奏               │
│  ──────────────────────────────────────────────────────│
│  节奏             │ 持续时间模式、节拍、律动           │
│  ──────────────────────────────────────────────────────│
│  音色/纹理     │ 乐器配置、动态                       │
│  ──────────────────────────────────────────────────────│
│  微观变化    │ 装饰音、表达、人性化                   │
│                                                         │
└─────────────────────────────────────────────────────────┘

随机生成

马尔可夫链旋律

import random
from collections import defaultdict

class MarkovMelodyGenerator:
    """使用马尔可夫链生成旋律"""

    def __init__(self, order=2):
        self.order = order
        self.transitions = defaultdict(list)

    def train(self, melodies):
        """从现有旋律学习(MIDI音符列表)"""
        for melody in melodies:
            for i in range(len(melody) - self.order):
                state = tuple(melody[i:i + self.order])
                next_note = melody[i + self.order]
                self.transitions[state].append(next_note)

    def generate(self, length, seed=None):
        """生成新旋律"""
        if seed is None:
            seed = random.choice(list(self.transitions.keys()))

        melody = list(seed)

        for _ in range(length - self.order):
            state = tuple(melody[-self.order:])
            if state in self.transitions:
                next_note = random.choice(self.transitions[state])
            else:
                # 回退:从所有可能的下一个音符中随机选择
                next_note = random.choice(
                    [n for notes in self.transitions.values() for n in notes]
                )
            melody.append(next_note)

        return melody

加权随机选择

def weighted_choice(options, weights):
    """使用自定义概率分布选择"""
    total = sum(weights)
    r = random.uniform(0, total)
    cumulative = 0
    for option, weight in zip(options, weights):
        cumulative += weight
        if r <= cumulative:
            return option
    return options[-1]

# 音阶度概率(倾向音)
scale_weights = {
    1: 0.20,  # 主音 - 稳定,常见
    2: 0.10,  # 上主音 - 经过
    3: 0.15,  # 中音 - 稳定
    4: 0.10,  # 下属音 - 倾向到3
    5: 0.20,  # 属音 - 稳定
    6: 0.10,  # 下中音 - 相关大调/小调
    7: 0.05,  # 导音 - 强倾向
    8: 0.10   # 八度
}

def generate_scale_melody(length, key='C', scale='major'):
    degrees = list(scale_weights.keys())
    weights = list(scale_weights.values())
    melody = [weighted_choice(degrees, weights) for _ in range(length)]
    return [degree_to_midi(d, key, scale) for d in melody]

基于文法的生成

音乐结构的L系统

class MusicalLSystem:
    """用于生成乐句的L系统"""

    def __init__(self):
        self.rules = {
            'A': 'AB',    # 前句扩展为前句 + 桥段
            'B': 'CA',    # 桥段扩展为后句 + 前句
            'C': 'DC',    # 后句扩展为发展 + 后句
            'D': 'A'      # 发展回到前句
        }
        self.interpretations = {
            'A': self._phrase_a,
            'B': self._phrase_b,
            'C': self._phrase_c,
            'D': self._phrase_d
        }

    def generate_structure(self, axiom='A', iterations=4):
        """生成形式结构"""
        result = axiom
        for _ in range(iterations):
            result = ''.join(self.rules.get(c, c) for c in result)
        return result

    def realize(self, structure):
        """将结构转换为音乐乐句"""
        phrases = []
        for symbol in structure:
            if symbol in self.interpretations:
                phrases.append(self.interpretations[symbol]())
        return phrases

    def _phrase_a(self):
        # 前句:紧张构建乐句
        return generate_phrase(contour='ascending', cadence='half')

    def _phrase_b(self):
        # 桥段:过渡材料
        return generate_phrase(contour='static', cadence='deceptive')

    def _phrase_c(self):
        # 后句:解决乐句
        return generate_phrase(contour='descending', cadence='authentic')

    def _phrase_d(self):
        # 发展:变化材料
        return generate_phrase(contour='varied', cadence='half')

节奏生成文法

class RhythmGrammar:
    """用于节奏生成的上下文无关文法"""

    def __init__(self):
        # 非终结符与产生规则
        self.rules = {
            'MEASURE': [
                ['HALF', 'HALF'],
                ['QUARTER', 'QUARTER', 'QUARTER', 'QUARTER'],
                ['DOTTED_HALF', 'QUARTER'],
                ['BEAT', 'BEAT', 'BEAT', 'BEAT']
            ],
            'HALF': [
                ['QUARTER', 'QUARTER'],
                ['half']
            ],
            'QUARTER': [
                ['EIGHTH', 'EIGHTH'],
                ['quarter'],
                ['SIXTEENTH', 'SIXTEENTH', 'EIGHTH']
            ],
            'BEAT': [
                ['quarter'],
                ['EIGHTH', 'EIGHTH'],
                ['TRIPLET']
            ],
            'EIGHTH': [
                ['eighth'],
                ['SIXTEENTH', 'SIXTEENTH']
            ],
            'TRIPLET': [
                ['triplet', 'triplet', 'triplet']
            ],
            'SIXTEENTH': [
                ['sixteenth']
            ]
        }

    def generate(self, symbol='MEASURE'):
        """递归扩展文法"""
        if symbol not in self.rules:
            return [symbol]  # 终结符

        # 选择随机产生规则
        production = random.choice(self.rules[symbol])

        result = []
        for s in production:
            result.extend(self.generate(s))

        return result

基于约束的和声

声部进行规则

class HarmonyGenerator:
    """生成满足声部进行约束的和弦进行"""

    def __init__(self, key='C', mode='major'):
        self.key = key
        self.mode = mode
        self.chord_vocabulary = self._build_chords()

    def generate_progression(self, length=8):
        """生成满足约束的进行"""
        progression = [self._tonic_chord()]  # 从主和弦开始

        for _ in range(length - 2):
            current = progression[-1]
            candidates = self._valid_next_chords(current)
            next_chord = self._select_chord(candidates, current)
            progression.append(next_chord)

        # 以终止式结束
        progression.append(self._dominant_chord())
        progression.append(self._tonic_chord())

        return progression

    def _valid_next_chords(self, current):
        """通过声部进行约束过滤和弦"""
        candidates = []
        for chord in self.chord_vocabulary:
            if self._check_voice_leading(current, chord):
                candidates.append(chord)
        return candidates

    def _check_voice_leading(self, chord1, chord2):
        """检查声部进行规则"""
        # 无平行五度
        if self._has_parallel_fifths(chord1, chord2):
            return False
        # 无平行八度
        if self._has_parallel_octaves(chord1, chord2):
            return False
        # 解决倾向音
        if not self._resolves_tendencies(chord1, chord2):
            return False
        # 限制声部移动
        if self._excessive_movement(chord1, chord2):
            return False
        return True

功能和声

# 和弦功能概率
PROGRESSION_TENDENCIES = {
    'I':   {'IV': 0.3, 'V': 0.3, 'vi': 0.2, 'ii': 0.1, 'iii': 0.1},
    'ii':  {'V': 0.7, 'vii': 0.2, 'IV': 0.1},
    'iii': {'vi': 0.4, 'IV': 0.3, 'ii': 0.2, 'I': 0.1},
    'IV':  {'V': 0.4, 'I': 0.2, 'ii': 0.2, 'vii': 0.1, 'vi': 0.1},
    'V':   {'I': 0.6, 'vi': 0.3, 'IV': 0.1},
    'vi':  {'IV': 0.3, 'ii': 0.3, 'V': 0.2, 'I': 0.1, 'iii': 0.1},
    'vii': {'I': 0.5, 'iii': 0.3, 'vi': 0.2}
}

def generate_functional_progression(length):
    progression = ['I']
    for _ in range(length - 1):
        current = progression[-1]
        tendencies = PROGRESSION_TENDENCIES[current]
        next_chord = weighted_choice(
            list(tendencies.keys()),
            list(tendencies.values())
        )
        progression.append(next_chord)
    return progression

适应性和交互式音乐

参数驱动生成

class AdaptiveComposer:
    """响应外部参数的音乐"""

    def __init__(self):
        self.parameters = {
            'energy': 0.5,      # 0-1:平静到激烈
            'tension': 0.5,     # 0-1:协和到不协和
            'density': 0.5,     # 0-1:稀疏到密集
            'tempo_factor': 1.0 # 节拍乘数
        }

    def update_parameter(self, name, value):
        self.parameters[name] = max(0, min(1, value))

    def generate_measure(self):
        """生成适应当前参数的音乐"""
        energy = self.parameters['energy']
        tension = self.parameters['tension']
        density = self.parameters['density']

        # 调整音乐元素
        note_density = int(4 + density * 12)  # 4-16音符
        velocity_range = (40 + int(energy * 40), 80 + int(energy * 47))

        # 张力影响和声
        if tension < 0.3:
            chord_pool = ['I', 'IV', 'V', 'vi']  # 协和
        elif tension < 0.7:
            chord_pool = ['ii', 'iii', 'IV', 'V', 'vi']  # 混合
        else:
            chord_pool = ['ii', 'vii', 'V7', 'bVII', 'iv']  # 紧张

        # 使用调整参数生成
        return self._generate_notes(
            density=note_density,
            velocity_range=velocity_range,
            harmonic_pool=chord_pool
        )

游戏音频适应系统

class GameMusicSystem:
    """游戏的分层适应性音乐"""

    def __init__(self):
        self.layers = {
            'ambient': {'volume': 1.0, 'active': True},
            'percussion': {'volume': 0.0, 'active': False},
            'melody': {'volume': 0.0, 'active': False},
            'intensity': {'volume': 0.0, 'active': False}
        }
        self.current_state = 'exploration'

    def set_game_state(self, state, transition_time=2.0):
        """基于游戏状态交叉淡化层次"""
        presets = {
            'exploration': {
                'ambient': 1.0, 'percussion': 0.0,
                'melody': 0.3, 'intensity': 0.0
            },
            'tension': {
                'ambient': 0.7, 'percussion': 0.3,
                'melody': 0.5, 'intensity': 0.3
            },
            'combat': {
                'ambient': 0.3, 'percussion': 1.0,
                'melody': 0.7, 'intensity': 1.0
            },
            'victory': {
                'ambient': 0.5, 'percussion': 0.5,
                'melody': 1.0, 'intensity': 0.0
            }
        }

        target = presets.get(state, presets['exploration'])
        self._crossfade_to(target, transition_time)
        self.current_state = state

输出格式

MIDI生成

from midiutil import MIDIFile

def create_midi(melody, filename='output.mid', tempo=120):
    """导出旋律到MIDI文件"""
    midi = MIDIFile(1)  # 一个轨道
    track = 0
    channel = 0
    time = 0
    volume = 100

    midi.addTempo(track, 0, tempo)

    for note in melody:
        pitch = note['pitch']
        duration = note['duration']
        midi.addNote(track, channel, pitch, time, duration, volume)
        time += duration

    with open(filename, 'wb') as f:
        midi.writeFile(f)

最佳实践

音乐连贯性

  1. 重复与变化:重复主题但变化
  2. 动机发展:转换小想法
  3. 分层结构:乐句 → 段落 → 乐章
  4. 紧张与释放:随时间构建和解决

避免常见陷阱

  • 纯随机听起来混乱——添加约束
  • 过多规则听起来机械——添加随机变化
  • 用实际音频测试,不仅是数据
  • 考虑表演/可演奏性

参考资料

  • references/music-theory-primer.md - 生成所需的基本音乐理论
  • references/markov-music.md - 高级马尔可夫链技术
  • references/midi-reference.md - MIDI规范和库