You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python作曲辅助软件:调式音符通用生成及规则化构建需求

嘿,很高兴能帮到你这个作曲辅助软件的开发!我来一步步拆解你的问题,从通用逻辑到Python实现都给你捋清楚。

通用生成调内音符的核心逻辑

所有调式的本质都是以根音为起点,按照固定的半音间隔序列推导出来的。在12平均律体系下,我们可以先把所有音名按半音顺序列出来,这是生成所有调的基础:

# 12平均律音名列表(用升音统一标识,也可换成降音版本,保持逻辑一致即可)
chromatic_scale = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']

不同调式对应不同的半音间隔规则,比如:

  • 自然大调(像你提到的C大调)的间隔序列是:大二度(W, 2个半音)、大二度(W)、小二度(H,1个半音)、大二度(W)、大二度(W)、大二度(W)、小二度(H),转换成数字就是[2,2,1,2,2,2,1]
  • 自然小调的间隔序列则是[2,1,2,2,1,2,2],其他调式也可以用类似的半音数值来定义。

通用生成步骤很简单:

  1. 找到根音在半音阶列表中的索引(比如C的索引是0,D是2)
  2. 从根音索引开始,依次加上间隔列表中的每个数值,每次计算后对12取模(避免超出半音阶的12个音范围)
  3. 根据计算出的索引,从半音阶列表中取出对应的音名,就能得到完整的调内音符。
Python实现调式生成函数

结合你的需求,我们可以写一个可复用的函数,完全不需要硬编码每个调的音符,只需要传入根音和调式间隔规则即可:

def generate_scale(root_note, intervals):
    chromatic = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
    # 忽略大小写匹配根音索引
    start_idx = chromatic.index(root_note.upper())
    scale = []
    current_idx = start_idx
    for interval in intervals:
        scale.append(chromatic[current_idx])
        current_idx = (current_idx + interval) % 12
    # 可选:添加八度根音,让音阶更完整
    scale.append(chromatic[start_idx])
    return scale

# 示例:生成C大调音阶
major_intervals = [2,2,1,2,2,2,1]
c_major = generate_scale('C', major_intervals)
print("C大调音阶:", c_major)
# 输出: ['C', 'D', 'E', 'F', 'G', 'A', 'B', 'C']
扩展:基于规则生成变化音程(比如增四度)

你提到的“增四度是纯四度升半音”这类规则,同样可以用半音逻辑实现:

  • 纯四度对应的半音数是5(比如C到F是5个半音)
  • 增四度就是5 + 1 = 6个半音(C到F#)
  • 同理,纯五度是7个半音,减五度就是7 - 1 = 6个半音(和增四度是等音,但音乐功能不同)

你可以写一个音程计算的辅助函数,基于基础音程的半音数,通过加减半音来生成各种变化音程:

def calculate_interval(note, interval_semitones):
    chromatic = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
    start_idx = chromatic.index(note.upper())
    target_idx = (start_idx + interval_semitones) % 12
    return chromatic[target_idx]

# 示例:计算C的纯四度和增四度
perfect_fourth = calculate_interval('C', 5)
augmented_fourth = calculate_interval('C', 5 + 1)
print(f"C的纯四度: {perfect_fourth}, 增四度: {augmented_fourth}")
# 输出: C的纯四度: F, 增四度: F#

这样一来,你完全不需要硬编码任何调的音符或音程,所有内容都基于半音规则动态生成,完美契合你想要的“用规则定义调”的思路。

内容的提问来源于stack exchange,提问作者Michael Hackman

火山引擎 最新活动