iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
AI & Data

AI Voice Conversion系列 第 18

【Day18】在 Python 裡頭利用 Mido 進行編曲

  • 分享至 

  • xImage
  •  

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


上一篇
【Day17】音樂與自然語言處理的奇妙關聯
下一篇
【Day19】 用 4 種不同的 GAN 模型生成音樂簡介
系列文
AI Voice Conversion30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言