天天看點

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

【python腳本系列】利用mido庫解析midi檔案

      Hallo大家好~~我是Lampard猿奮

      昨天寫了關于Midi數字化樂器接口的文章,介紹了midi是一組代表音樂參數(如音高,動态,節奏等等 )的标準化代碼,是音樂與計算機之間互動的語言。那麼這個語言究竟是怎麼組成,是什麼資料結構呢,下面就借助python的mido庫和大家一起打開這個黑盒

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

(一)幾個重要概念

(1)Channel通道

      channel是指定的0~15的一個值,因為MIDI檔案給我們提供了預設的16個通道,每一個通道可以對應一種樂器,相當于midi支援一首歌曲裡同時使用16種樂器進行演奏

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

      當然每一個通道對應的樂器并不是固定的,我們可以代碼Message('program_change', channel, program, time=0)改變其對應關系,也就是說雖然同時支援16種樂器,但16種樂器不需要是固定的,上述接口中program代表着樂器Id,更多樂器Id相關可以跳轉至此:【Midi音色表】

(2)Track音軌

      音軌,音軌與通道并不是一一對應,而是可以多對多的關系。音軌是邏輯上的劃分,比如可以将鋼琴的左手演奏放在track 1,右手演奏放在track 2。但是輸出時候,都是對應輸出到鋼琴的通道。你也可以隻設定一個track 1,并且在裡面記錄着不同通道的消息。另外,還經常将track 0用來存儲midi的作者、版權、音軌名、樂器名等元資訊

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

(3)Event事件

      事件也叫做消息(在mido庫中使用message表示)。包括三種事件meta event元消息,midi event主消息, sysex event系統消息

      元消息上文有提及是作者,版權,音樂名等資訊的存在track0中,系統消息是存儲midi系統不同版本的資訊,主要需要留意的就是midi消息

       midi有多種資訊類型,我們可以參考mido文檔去查閱:【mido庫文檔】,而我們主要需要關注兩個資訊note_on和note_off

(4)note_on

      note_on消息,可以了解為音符的開始(按下),其格式為Message('note_on', note, velocity, time, channel)

      其中note是0~127的一個數字,代表音符的高低,通過實踐證明60代表的音高是C4

      velocity代表音強,也是0~127的一個數字,預設為64,若要展現音符強度的變化可以修改它

      time是時間變量,是十分複雜的一個參數,在note_on資訊這裡可以了解為該音符寫在前一個音符結束多久之後,機關是微秒(ms)

      channel同上一個函數一樣,代表通道的編号,即将這個音符寫到哪個通道之上,這可能起到更改樂器的效果

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

(5)note_off

      note_off消息,可以了解為音符的結束(擡起),一般緊跟在note_on消息之後,其格式與上面的相同Message('note_off', note, velocity, time, channel)

      note參數與note_on消息保持一緻,否則有可能不能成功寫入

      velocity同note_on保持一緻就好

      time在此處表示的意義是音符的持續時間,也是以微秒(ms)為機關

      channel也是表示通道号,與note_on保持相同即可

(二)使用Mido庫

      看了那麼多字感覺頭都大了,好像也不太了解說的是什麼。那下面還是直覺一些用Mido庫給我們提供的案例來分析一下Midi檔案的結構吧【mido庫示例】

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

 (1) 建立一個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')
           

      這段示例代碼雖然短,可是已經将編寫MIDI檔案的基本思路完全表達出來了:

    1. 首先建立一個MidiFile對象

    2.建立一個(或多個)MidiTrack對象,并将其append到MidiFile中

    3.向一個(或多個)MidiTrack對象内添加Message對象(包括program_change(變更通道對應樂器)、note_on(按下)、note_off(擡起)等)

    4.儲存MidiFile對象

      我把這段代碼命名為makeMidi.py,執行一遍就能擷取到我們生成的new_song.midi檔案

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

 (2) 解析這個MIdi檔案

      然後就是讀取這個midi,mido庫同樣給出了示例,邏輯很簡單就是列印出這個midi檔案每一個音軌track的資訊    

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

       最後我們看一下我們打出的日志,我把解析的腳本命名為readMidi.py,執行後可以看到我們剛才輸入的資訊,在音軌0的32ms後執行一次的點選動作,對應的音色是64

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案

      如果我們不想列印出全部資訊,指向關注不同track之間的note_on和note_off的資訊,我們可以msg.type == “note_on/note_off”這樣來判别

(三)結語

      當我們能夠解析出midi的資訊之後就可以和音效制作樂譜的同學溝通啦。距離實作音遊玩法也跟進了一步,待玩法進度推進後我再繼續更新~~

      感謝閱讀,點贊,關注!!!

【python腳本系列】利用mido庫解析midi檔案【python腳本系列】利用mido庫解析midi檔案