【Day18】在 Python 里头利用 Mido 进行编曲

Message in MIDI

书接昨日,在 MIDI 里面有固定的格式在记录声音的讯号,因为实在是太多了我们不会一一举例,这边只说明几个常用到的,完整的官方文件请参照这里

1.Program change
用於更改不同 channel 的乐器音色

    Message('program_change',channel,id,time =0)
    
  • channel 为 0 ~ 15,更改这个值来更改声音的通道,MIDI 默认有 16 个通道
  • id 是乐器的编号,你可以在这里查到,总共有 128 种
  1. Note on
    音符的开始

    Message('note_on',note,vel,time,channel)
    
  • note 值为 0~127,代表音高,比方说 60 就对应到 C4
  • vel 值为 0~127,代表声音的强度,默认是 64
  • time 的意思是 "这个音符要在前一个音符结束後过多久开始"
  1. Note off
    音符的结束,通常紧跟在 Note on 後面

     Message('note_off',note,vel,time,channel)
    
  2. Control change (cc)
    控制声音,比方说踩钢琴的延音踏板这类的操作

     Message('control_change',channel,control,value,time)
    
  • control 可以选择要对声音做哪些奇妙操作,详细请参考这篇,这里列几个常用到的操作

    1. 64 - 延音踏版
    2. 71 - Harmonic Intens. 共鸣,可以控制声音较突显或隐诲
    3. 72 - Release Time 音符结束之後,声音渐弱至完全没有的时间
    4. 73 - Attack Time 音符开始之後,从无声爬到至最高点的时间
    5. 74 - Brightness 调整声音的明亮度
  • value 则是控制实际操作的程度,比方说踩延音踏版这件事在 value =< 63 是 off 反之则是 on

开始编曲吧!

我们试着来编追追追 ~

from mido import Message, MidiFile, MidiTrack
mid = MidiFile()
track = MidiTrack()

 def play_part(track, note, len_ ,note_bias=0,vel=1.0,delay=0,change=False,double=False):
    # 每个节拍的时间长度
    temple = 60*60*10/75
    # 大调,参考别人的做法的,我也不是很懂乐理
    major_notes = [0,2,2,1,2,2,2,1]
    # C4 - 正中间的 DO
    base_note = 60
    bias = note_bias*12 + sum(major_notes[0:note])
    vel = round(64*vel)
    t_start = round(delay*temple)
    t_end =  round(temple*len_)
    if not double:
        track.append(Message("note_on",  note=base_note+bias,velocity=vel,time=t_start))
        track.append(Message("note_off", note=base_note+bias,velocity=vel,time=t_end))
    if change:
        track.append(Message("control_change",channel=0,control=64,value=64,time=t_start))
        track.append(Message("control_change",channel=0,control=64,value=0,time=t_end))
    if double:
        track.append(Message("program_change", channel=1,program=41 ,time = t_start))
        track.append(Message("note_on",channel=1, note=base_note+bias,velocity=vel,time = t_start))
        track.append(Message("note_off",channel=1, note=base_note+bias,velocity=vel,time = t_end))
        track.append(Message("program_change", channel=1,program=0 ,time=t_end))
    return track
    
    track = play_part(track,6,0.5)
    
######## 第一段 ###########

track = play_part(track,5,0.5)
track = play_part(track,6,0.5)
track = play_part(track,6,0.5)
track = play_part(track,5,0.5)
track = play_part(track,3,0.5)

track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,2,0.5)

track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,2,0.5)
track = play_part(track,3,1.5)
track = play_part(track,5,0.5)
track = play_part(track,2,0.5)

track = play_part(track,3,1.0,change=True)

track = play_part(track,3,0.25,double=True)
track = play_part(track,5,0.25,double=True)
track = play_part(track,2,0.25,double=True)


######## 第二段 ###########

track = play_part(track,3,0.5)
track = play_part(track,6,0.5)
track = play_part(track,5,0.5)
track = play_part(track,2,0.5)
track = play_part(track,5,0.5)
track = play_part(track,2,0.5)

track = play_part(track,6,0.5,-1)
track = play_part(track,2,0.5)
track = play_part(track,1,0.5)
track = play_part(track,6,0.5,-1)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)

track = play_part(track,2,0.5)
track = play_part(track,5,1.5)
track = play_part(track,2,0.5)
track = play_part(track,2,0.5)
track = play_part(track,3,0.25)
track = play_part(track,5,0.25)


track = play_part(track,5,1.5)
track = play_part(track,5,0.5,-1)
track = play_part(track,5,0.5,-1)

track = play_part(track,6,0.5,-1)
track = play_part(track,6,1.0,-1,change=True)

track = play_part(track,5,0.5,-1,double=True)
track = play_part(track,6,0.5,-1,double=True)
track = play_part(track,6,1.5,-1,double=True)

######## 剩下的请加油 XD ###########

mid.tracks.append(track)
mid.save('new_song.mid')

小结

今天我们用 Python 实际编了一首曲子,其实体验不是说很好,玩音乐的话果然还是要用一些专业的软件比较好,但如果是要拿来做一些研究还是要从 python 出发,透过这次编曲也可以比较了解 MIDI 的运作>

参考资料

乐谱

/images/emoticon/emoticon09.gif/images/emoticon/emoticon13.gif/images/emoticon/emoticon14.gif/images/emoticon/emoticon22.gif/images/emoticon/emoticon28.gif


<<:  【Day18】在使用者模式移除data-test属性,浅谈React Hook (•‿•)

>>:  [Day 4] 排版布局Grid

网络资讯撷取神器 – 爬虫程序 (PYTHON SELENIUM)

我们在举办【Python 大数据培训课程】时,发现很多学员对 Selenium 有以下问题,在此解释...

什麽是Vaadin - day01

Vaadin 简介 Vaadin 是一款由芬兰 Vaadin 公司所开发,用於建构网路应用程序和网站...

Day 23-state manipulation 之五:terraform import,专案中途导入 terraform 必经之路

上篇介绍 state rm,强制 terraform 遗忘已经存在的 state。然而 state ...

Day27-机器学习(1) SVM

SVM简单说明 为一种监督学习的方法,其原理是会根据资料的数据,划出一条界线来区分各群 我举个例子说...

NIST SP 800-53A R4-测试深度&测试范围

“覆盖范围属性解决了评估的范围或广度。” (NIST SP 800-53A)测试的范围与测试范围有关...