昨天我們有提到,我們想要生的是像小星星這樣子古典鋼琴音樂,像這樣子的音樂音色是固定,音高也是有限範圍內的排列組合,所以重要的訊息並不會是這段聲音的特徵,反而是排列組合,也就是我們昨天講的套路
如果把它跟自然語言處理做一個聯想的話,我是這樣子想像的
Do = 我 Re = 好 Mi = 帥
# 兩隻老虎
Do Re Mi Do Do Re Mi Do => 我好帥我我好帥我
# 隨便亂排
Re Mi Re Mi Mi Re Do Do => 好帥好帥帥好我我
雖然這個舉例很不精確XD, 但你可以看的出來兩隻老虎的那段排列是比較能知道它的意思的
再舉一個例子來說明音樂與自然語言在語法上的相似性
假設我現在說 "我要去星巴克買...",你大概會猜我要去買 "咖啡"
同樣道理如果我現在在彈兩隻老虎 "Do Re Mi Do Do Re Mi ..." 你也可以猜到下一個音是 "Do"
這兩件事情本質是一樣的,處理自然語言的時候我們透過 LSTM 好利用過去的訊息來預測未來,同樣的招式也許也適用在音樂上面。
為了讓我們更快速的把鋼琴音樂轉成像是文本的問題來解決,我們這邊採用 MIDI 格式的檔案來處理
MIDI 格式的檔案是一種工業標準的電子通訊協定,它為電子樂器等演奏裝置定義各種音符或彈奏碼,可以讓電子樂器、電腦、手機或是舞台演出的專業設備彼此連接,調整和同步。
MIDI 檔案不傳送聲音,只傳送像是音調和音樂強度的數據,音量,顫音和相位等參數的控制訊號,還有設定節奏的時脈訊號。在不同的電腦上,輸出的聲音也因音源器不同而有差異,比方說在 Windows 就是鋼琴音,你可以去下載一些專門在玩 MIDI 格式的軟體,就可以把它轉成其他樂器的聲音。
更棒的是因為它記錄的東西很少,所以通常一個檔案只需要 10KB
好消息是,Python 本身就有提供可以處理 MIDI 的 Lib,下面是官方的範例
from mido import MidiFile
mid = MidiFile('song.mid')
讀進來之後,它可能有很多個音軌
for i, track in enumerate(mid.tracks):
print('Track {}: {}'.format(i, track.name))
for msg in track:
print(msg)
也可以自己生 MIDI 音樂
from mido import Message, MidiFile, MidiTrack
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
track.append(Message('program_change', program=12, time=0))
track.append(Message('note_on', note=64, velocity=64, time=32))
track.append(Message('note_off', note=64, velocity=127, time=32))
mid.save('new_song.mid')
上面這段程式碼並不能演奏出什麼東西,它只是跟你說明使用概念
所以重點其實是 Message 裡頭要添加什麼,我們明天再實際用這個編一首歌吧,這樣也可以知道裡面到底裝什麼東西。