Python编曲实践(二):和弦的实现和进行

15 篇文章 15 订阅
8 篇文章 7 订阅

前言

上一篇文章 中我简单介绍了如何使用Mido这个库在Python中实现MIDI编程,分享了我的经验和心得,但是单音轨的纯音符堆砌听起来太单薄了,故本篇文章介绍如何轻松添加和弦音轨,使得乐曲更加饱满、丰富。

和弦的背景知识

和弦,简单来讲就是三个及以上的不同音高的音符的组合。这些音符可以同时演奏,形成混响的效果,也可以按照一定的组合方式交替演奏。最常见的和弦有两种:三和弦和七和弦,前者由三个音符组成,又分为四种;后者由四个音符组成,又分为8种,具体分类见下面的表格:

名称音程
大三和弦大三度、纯五度
小三和弦小三度、纯五度
增三和弦大三度、增五度
减三和弦小三度、减五度
名称音程
大七和弦大三度、完全五度、大七度
小七和弦小三度、完全五度、小七度
属七和弦(大小七和弦)大三度、完全五度、小七度
小大七和弦小三度、完全五度、大七度
半减七和弦小三度、减五度、减七度
减七和弦小三度、减五度、减七度
增七和弦大三度、增五度、小七度
增大七和弦大三度、增五度、大七度

下面这个图是 维基百科 的十二平均律表格,显示了不同音程名称与间隔半音数的对应关系:
十二平均律

结合十二平均律的音程名称和间隔半音数的对照关系,我们就可以动手写和弦了.

编程实现

首先编写一个方程用于得到不同和弦对应的音程关系:

def get_chord_arrangement(name):
    chord_dict = {
        'maj3': [0, 4, 7, 0],  # 大三和弦 根音-大三度-纯五度
        'min3': [0, 3, 7, 0],  # 小三和弦 根音-小三度-纯五度
        'aug3': [0, 4, 8, 0],  # 增三和弦 根音-大三度-增五度
        'dim3': [0, 3, 6, 0],  # 减三和弦 根音-小三度-减五度

        'M7': [0, 4, 7, 11],  # 大七和弦 根音-大三度-纯五度-大七度
        'Mm7': [0, 4, 7, 10],  # 属七和弦 根音-大三度-纯五度-小七度
        'm7': [0, 3, 7, 10],  # 小七和弦 根音-小三度-纯五度-小七度
        'mM7': [0, 3, 7, 11],  # 小大七和弦 根音-小三度-纯五度-大七度
        'aug7': [0, 4, 8, 10],  # 增七和弦 根音-大三度-增五度-小七度
        'augM7': [0, 4, 8, 11],  # 增大七和弦 根音-大三度-增五度-小七度
        'm7b5': [0, 3, 6, 10],  # 半减七和弦 根音-小三度-减五度-减七度
        'dim7': [0, 3, 6, 9]  # 减减七和弦 根音-小三度-减五度-减七度
    }

    chord = [0, 0, 0, 0]
    try:
        chord = chord_dict[name]
    except:
        print(traceback.format_exc())
    return chord

返回值是一个长度为4的一维数组,每一个值表示这个音符与根音相差的半音数。
然后编写一个用于将和弦添加到音轨中的函数add_chord:

def add_chord(root, name, format, length, track, root_base=0, channel=3):
    bpm = get_bpm(track)
    major_notes = [0, 2, 2, 1, 2, 2, 2, 1]
    notes = ['C', 'D', 'E', 'F', 'G', 'A', 'B']
    notes_dict = {}
    for i, note in enumerate(notes):
        notes_dict[note] = 60 + sum(major_notes[0:i+1])
    root_note = notes_dict[root] + root_base*12
    chord = get_chord_arrangement(name)
    meta_time = 60 * 60 * 10 / bpm
    time = round(length / len(format) * meta_time)

    for dis in format:
        note = root_note + chord[dis]
        track.append(Message('note_on', note=note, velocity=56, time=0, channel=channel))
        track.append(Message('note_off', note=note, velocity=56, time=time, channel=channel))

在参数中:

  • root是根音的名字,这里我们考虑的音符是在notes数组中给出,暂时不考虑升降音为根音的情况;root_base是根音所在的音域;
  • format是用于演奏和弦的方式,用一维数组表示,数组表示和弦中第几个音符,比如 [0, 1, 2, 3, 2, 1] ;
  • length是整个和弦演奏的时长,用占全音符长度的数量来表示
    通过这个函数中的循环,我们可以按照format指示的方式将和弦添加到MIDI音轨之中。

对于《大海啊,故乡》,我按照 网上的吉他谱 为它添加了如下的和弦模式:

def chord(track):
    format = [0, 1, 2, 3, 2, 1]
    add_chord('C', 'M7', format, 3, track)
    add_chord('E', 'm7', format, 3, track)
    add_chord('C', 'M7', format, 3, track)
    add_chord('D', 'm7', format, 3, track)
    add_chord('G', 'Mm7', format, 3, track, -1)
    add_chord('D', 'm7', format, 3, track)
    add_chord('F', 'M7', format, 3, track, -1)
    add_chord('C', 'M7', format, 3,  track)

    add_chord('C', 'M7', format, 3,  track)
    add_chord('G', 'M7', format, 3, track, -1)
    add_chord('F', 'M7', format, 3, track, -1)
    add_chord('G', 'M7', format, 3, track, -1)
    add_chord('C', 'M7', format, 3, track)
    add_chord('D', 'm7', format, 3, track)
    add_chord('G', 'Mm7', format, 3, track)
    add_chord('C', 'M7', format, 3, track)

    add_chord('C', 'M7', format, 3,  track)
    add_chord('G', 'M7', format, 3, track, -1)
    add_chord('F', 'M7', format, 3, track, -1)
    add_chord('G', 'M7', format, 3, track, -1)
    add_chord('C', 'M7', format, 3, track)
    add_chord('D', 'm7', format, 3, track)
    add_chord('G', 'Mm7', format, 3, track)
    add_chord('C', 'M7', format, 3, track)

总结

加上和弦之后,我的MIDI文件在MidiEditor中显示如下:
在这里插入图片描述感谢阅读,完整的项目代码详见 Github - Truedick23/MusicCritique

参考资料

和弦 - 维基百科
十二平均律 - 维基百科

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
Python自动化运维是利用Python编程语言来实现自动化运维的技术和实践。随着云计算和大数据的发展,运维工作变得越来越复杂和繁琐,手动操作已经无法满足需求,因此自动化运维成为了必然趋势。 Python作为一种简洁、易于学习和灵活的编程语言,被广泛应用于自动化运维领域。它结合了丰富的标准库和第三方库,可以方便地实现系统监控、日志分析、配置管理、批量操作等常见运维任务。 在技术方面,Python提供了各种库和工具,如Paramiko、Fabric、Ansible等,用于实现SSH连接、远程执行命令、批量部署等操作。此外,Python还可以通过调用其他系统的API接口,实现与云平台、容器技术等的集成。同时,Python还支持多线程和多进程,可以提高程序的并发处理能力。 在实践方面,Python自动化运维可以应用于各种场景。例如,可以用Python编写脚本来监控服务器的性能指标,定时生成报表;可以使用Python来自动化配置管理,实现快速、一致性的配置变更;还可以通过Python批量部署应用程序,简化操作流程,提高效率;此外,还可以利用Python实现日志分析和故障排查等任务。 总结来说,Python自动化运维是一种利用Python编程语言实现系统运维自动化的技术和实践。它能够提高运维工作的效率和可靠性,减少人工操作的复杂性和错误率,并且具备广泛的应用场景和丰富的技术支持。随着自动化运维的普及和Python的持续发展,Python自动化运维将在未来发挥更加重要的作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值