前言

在前面三篇文章中,我介绍了如何通过Python的Mido库添加旋律、和弦和模拟滑音、颤音。然而,鼓的作用也是不可忽视的,它就像骨骼一样支撑起整个音乐,而编辑鼓点的样式也为想象力的发挥提供了无限空间,是十分愉悦的事情,本篇文章我就介绍如何向MIDI文件中添加鼓的音轨。

专属频道

同其他乐器不同,MIDI格式为鼓组提供了专属的频道,默认在10号频道,并在这个频道的40多个音符对应处替换上了不同种类的鼓点样式,为了更方便调用,我做成了一个函数,以供参考:

def get_drum_dict():drum_dict = {'acoustic_bass': 35,'bass1': 36,'side_stick': 37,'acoustic_snare': 38,'hand_clap': 39,'electric_snare': 40,'low_floor_tom': 41,'closed_hi-hat': 42,'high_floor_tom': 43,'pedal_hi-hat': 44,'low_tom': 45,'open_hi-hat': 46,'low-mid_tom': 47,'hi-mid_tom': 48,'crash_cymbal1': 49,'high_tom': 50,'ride_cymbal1': 51,'chinese_cymbal': 52,'ride_bell': 53,'tambourine': 54,'splash_cymbal': 55,'cowbell': 56,'crash_cymbal2': 57,'vibraslap': 58,'ride_cymbal2': 59,'hi_bongo': 60,'low_bongo': 61,'mute_hi_bongo': 62,'open_hi_bongo': 63,'low_conga': 64,'high_timbale': 65,'low_timbale': 66,'high_agogo': 67,'low_agogo': 68,'cabasa': 69,'maracas': 70,'short_whistle': 71,'long_whistle': 72,'short_guiro': 73,'long_guiro': 74,'claves': 75,'hi_wood_block': 76,'low_wood_block': 77,'mute_cuica': 78,'open_cuica': 79,'mute_triangle': 80,'open_triangle': 81}return drum_dict

可见从35到81全是对应的鼓的样式,对普通编曲而言肯定是够了。

编程实现

有了专属的频道,那么我们就能够很轻松地来创作自己的鼓组音轨了,为了方便我写了一个添加鼓点的函数,供大家参考:

def add_drum(name, time, track, delay=0, velocity=1):bpm = get_bpm(track)meta_time = 60 * 60 * 10 / bpmdrum_dict = get_drum_dict()try:note = drum_dict[name]except:print(traceback.format_exc())returntrack.append(Message('note_on', note=note, velocity=round(64 * velocity), time=delay, channel=9))track.append(Message('note_off', note=note, velocity=round(64 * velocity), time=round(meta_time * time), channel=9))

为了让自己的鼓点更加丰富一点,我添加了两个鼓的音轨,一个用于踩镲(Hi-Hat),主要是用于基本节奏的把握,另一个是军鼓(Snare)、嗵鼓(Tom)和强音钹(Crash Cymbal),用于使节奏更加Funky和Groovy,并在其他乐器空白间隙加入过门,使得音乐更加丰满。

  • 首先是镲轨,我编写得十分简单:
def hi_hat(track):for i in range(8):add_drum('open_hi-hat', 0.5, track, velocity=0.6)add_drum('closed_hi-hat', 0.5, track, velocity=0.6)add_drum('closed_hi-hat', 0.5, track, velocity=0.6)add_drum('open_hi-hat', 0.5, track, velocity=0.6)add_drum('closed_hi-hat', 0.5, track, velocity=0.6)add_drum('closed_hi-hat', 0.5, track, velocity=0.6)for i in range(16):add_drum('open_hi-hat', 0.5, track, velocity=0.6)add_drum('closed_hi-hat', 0.25, track, velocity=0.6)add_drum('closed_hi-hat', 0.25, track, velocity=0.6)add_drum('closed_hi-hat', 0.25, track, velocity=0.6)add_drum('closed_hi-hat', 0.25, track, velocity=0.6)add_drum('open_hi-hat', 0.5, track, velocity=0.6)add_drum('closed_hi-hat', 0.5, track, velocity=0.6)add_drum('closed_hi-hat', 0.5, track, velocity=0.6)
  • 然后是玩花儿的轨,我用了两个函数来实现:
def tom_and_snare_pt1(track):for i in range(7):add_drum('acoustic_snare', 0.5, track, velocity=0.8)add_drum('low_tom', 0.5, track, velocity=0.6)add_drum('low-mid_tom', 0.5, track, velocity=0.6)add_drum('acoustic_snare', 0.5, track, velocity=0.6)add_drum('low_tom', 0.25, track, velocity=0.8)add_drum('acoustic_snare', 0.5, track, velocity=0.8)add_drum('low-mid_tom', 0.25, track, velocity=0.6)add_drum('acoustic_snare', 0.5, track, velocity=0.8)add_drum('low_tom', 0.25, track, velocity=0.6)add_drum('low-mid_tom', 0.25, track, velocity=0.6)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('crash_cymbal1', 0.25, track, velocity=1.2)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('crash_cymbal2', 0.25, track, velocity=1.2)add_drum('acoustic_snare', 0.25, track, velocity=0.8)def tom_and_snare_pt2(track, num):for i in range(3): #6add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('low_tom', 0.5, track, velocity=0.6)add_drum('high_tom', 0.25, track, velocity=0.6)add_drum('low-mid_tom', 0.25, track, velocity=0.6)add_drum('acoustic_snare', 0.5, track, velocity=0.6)add_drum('low_tom', 0.25, track, velocity=0.8)add_drum('acoustic_snare', 0.5, track, velocity=0.9)add_drum('low-mid_tom', 0.125, track, velocity=0.6)add_drum('hi-mid_tom', 0.125, track, velocity=0.6)add_drum('acoustic_snare', 0.5, track, velocity=0.8)add_drum('low_tom', 0.25, track, velocity=0.6)add_drum('low-mid_tom', 0.25, track, velocity=0.6)add_drum('high_tom', 0.25, track, velocity=0.6)add_drum('low-mid_tom', 0.25, track, velocity=0.6)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('crash_cymbal1', 0.25, track, velocity=1.2)add_drum('high_tom', 0.25, track, velocity=0.6)add_drum('crash_cymbal2', 0.25, track, velocity=1.2)add_drum('low-mid_tom', 0.25, track, velocity=0.6)add_drum('acoustic_snare', 0.5, track, velocity=0.8)add_drum('low_tom', 0.25, track, velocity=0.6)add_drum('low-mid_tom', 0.25, track, velocity=0.6)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('acoustic_snare', 0.125, track, velocity=0.8)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('crash_cymbal1', 0.25, track, velocity=1.2)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('crash_cymbal2', 0.25, track, velocity=1.2)add_drum('acoustic_snare', 0.25, track, velocity=0.8)add_drum('high_tom', 0.125, track, velocity=0.9)add_drum('high_tom', 0.125, track, velocity=0.9)add_drum('hi-mid_tom', 0.125, track, velocity=0.9)add_drum('hi-mid_tom', 0.125, track, velocity=0.9)add_drum('low-mid_tom', 0.125, track, velocity=0.9)add_drum('low-mid_tom', 0.125, track, velocity=0.9)add_drum('low_tom', 0.125, track, velocity=0.9)add_drum('low_tom', 0.125, track, velocity=0.9)add_drum('high_floor_tom', 0.25, track, velocity=1.1)add_drum('high_floor_tom', 0.25, track, velocity=1.1)add_drum('low_floor_tom', 0.25, track, velocity=1.2)add_drum('low_floor_tom', 0.25, track, velocity=1.2)if num == 1:add_drum('crash_cymbal1', 0.25, track, velocity=1.2)add_drum('crash_cymbal2', 0.25, track, velocity=1.2)add_drum('crash_cymbal1', 0.25, track, velocity=1.2)add_drum('crash_cymbal2', 0.25, track, velocity=1.2)if num == 2:add_drum('low_floor_tom', 0.25, track, velocity=1.3)add_drum('low_floor_tom', 0.25, track, velocity=1.3)add_drum('chinese_cymbal', 1, track, velocity=1.9)

鼓组音轨的MIDI文件可参考 drum.mid
完整项目可参考 Github - Truedick23/MusicCritique

参考资料

  • MIDI Tutorial
  • GM 1 Sound Set

Python编曲实践(四):向MIDI文件中添加鼓组音轨相关推荐

  1. Python编曲实践(十一):通过PyQt5和PyGame开发的简易MIDI电钢琴,支持键盘控制、基础存储、音符可视化及调性提示等功能

    前言 这个项目是我在半年前从零开始进行开发的,主要是为了在学习Python编曲初期通过开发这一个电钢琴界面来练练手,并实现一些通用的基础函数来方便后续的项目使用.这一电钢琴软件的功能无法与正统的商业软 ...

  2. Python编曲实践(九):如何计算并估计音乐的调性(大/小调+主音)?Krumhansl-Schmuckler调性分析算法的原理与实现

    前言 之前,我在 Python编曲实践(五)中记录了构建MIDI数据集Free MIDI Library的过程,其中预处理阶段十分重要的一个步骤是移调,即把所有音乐的调性调整为C大调或A小调,这样会使 ...

  3. Python编曲实践(八):我,乔鲁诺·乔巴那,能用两百行代码写出JOJO黄金之风里我自己的出场曲!

    前言 前些天笔者写的文章 Python编曲实践(七):整整一百行Python代码写出黑人抬棺梗曲<Astronomia>的旋律 受到了大家的许多支持和好评,本篇文章挑战更复杂.更有挑战性, ...

  4. Python编曲实践(一):通过Mido和PyGame来编写和播放单轨MIDI文件

    前言 人工智能编曲是一个十分复杂的话题,而这一话题的起点便是选择一个良好的编曲媒介,使得开发者能够将AI的音乐灵感记录下来,并且能够很方便地将其播放.编辑.分享. MIDI文件是电脑编曲的一种通用格式 ...

  5. Python编曲实践(五):通过编写爬虫来爬取海量MIDI文件,预备构建数据集(附有百度云下载链接)

    前言 由于毕业设计的课题是通过CycleGAN搭建一个音乐风格转换系统,需要大量的音乐文件来训练神经网络,而MIDI文件作为最广泛使用的一种电脑编曲保存媒介,十分容易搜集资源,也有很多成熟的Pytho ...

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

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

  7. Python编曲实践(三):如何模拟“弯音轮”实现滑音和颤音效果

    前言 弯音轮,是在MIDI键盘或专业电子琴一旁安装的一个装置(如下图). 通过前后拨动滚轮,可以实现弯音和颤音的效果.这对于追求特殊电音效果的作曲者来说是必不可少的,而这两个技巧也是吉他等乐器演奏时十 ...

  8. 使用Python批量筛选上千个Excel文件中的某一行数据并另存为新Excel文件(下篇)

    点击上方"Python爬虫与数据挖掘",进行关注 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 野火烧不尽,春风吹又生. 大家好, ...

  9. c语言读取midi文件举例子,c# – 使用NAudio从MIDI文件中读取音符

    任务是使用NAudio库从MIDI文件中获取所有音符和时间.到目前为止,我从文件中获取所有笔记,但我无法得到他们的时间. Note noteOn = new Note(); //custom clas ...

最新文章

  1. 【Qt】Qt5.9连接MySQl5.7(亲自测试成功)
  2. Java笔记(基础第二篇)
  3. java 高并发第三阶段实战_Java 高并发第三阶段实战---Java并发包深入解析与使用详解...
  4. java 中时间计算_java中关于时间的计算
  5. 视觉SLAM笔记(56) 位姿图优化
  6. npm run build失败
  7. 科研|饶毅:科学在被淘汰的博士后引领下狂奔
  8. mysql5启动错误1067_win7 64位 mysql5.5启动服务报错无法启动,错误1067
  9. 6 | Spatial-based GNN/convolution模型之MoNET
  10. 代码可读性、可调式、可维护性
  11. U-Net-Convolutional Networks for Biomedical Image Segmentation论文翻译——中文版
  12. 计算机系统分别由,计算机系统由两部分组成它们分别是什么
  13. Spring Boot(一)之入门篇
  14. mt2503 [ShapeEngine]泰语音标字符发生偏移
  15. Java匿名内部类的用法(简单教学)
  16. python实现整数从低位到高位输出与从高位到低位输出
  17. Java序列化与反序列化的深度思考
  18. 声网 SDK 接入以及音视频通话应用开发指南
  19. 秋叶PPT高效训练营笔记 —— Day 1素材
  20. Direct3D 11编程总结

热门文章

  1. 《首先,打破一切常规》附录:发现12个问题
  2. 20 Rest高级客户端实践(六):搜索入门和基本API介绍
  3. [讨论]日本地震对中国软件服务外包行业的影响分析(宏观)
  4. (微信小程序毕业设计)基于微信小程序便捷记账系统
  5. BT Controller EDR2/EDR3的调试总结
  6. html怎么注释掉代码_HTML注释:如何注释掉您HTML代码
  7. ubuntu 10.04 wine qq2009
  8. 0x0000009f(0x0000009f蓝屏)
  9. php数字转人民币,php人民币数字转大写数字的简单示例
  10. 18个演讲PPT技巧,让你成为真正的演讲高手