2016-01-26 66 views
2

我試圖讀取一個MIDI文件,然後將每個音符(MIDI編號)轉換爲鍵盤上的模擬鍵盤(A,f,h,J,t ...)。如何將midi文件轉換爲按鍵(使用Python)?

我能夠讀取這樣的蟒蛇-MIDI庫的MIDI文件:

pattern = midi.read_midifile("example.mid") 

,我也可以模擬按鍵與pywin32像這樣:

shell = win32com.client.Dispatch("WScript.Shell") 
shell.SendKeys(key) 

但是我有不知道如何實際將midi數字(midi文件)轉換爲按鍵。

更準確地說我想MIDI數字轉換成筆記,然後注意到根據virtualpiano.net(61鍵),使該方案將播放鋼琴通過按下鍵盤上的相應按鈕,按鍵(可以按鍵協助鋼琴的設置,看看哪些鍵是什麼鍵)

當然,我也有按鍵之間等待但這是很容易的。

任何幫助表示讚賞。 (視窗10的64位(32位的Python 2.7))

+0

如果我正確地理解了您的問題,您需要能夠識別MIDI文件中的音符。你可以用困難的方式(直接解析文件)或使用現有的庫,例如[python-midi](https://github.com/vishnubob/python-midi)。 –

+0

好吧,我說「我可以用python-midi庫讀取任何MIDI文件」,我可以。這樣做沒有問題。其實我提到了和你一樣的圖書館。問題是我找不到任何關於如何將MIDI數字轉換爲C#-36或A-40(或任何正確名稱)的筆記的文檔 – alaswhu

回答

2

如果你看看你正在使用的midi模塊,你會發現有一些常數可以用來將音符轉換成MIDI數字,反之亦然。

>>> import midi 
>>> midi.C_0 # note C octave 0 
0 
>>> midi.G_3 # G octave 3 
43 
>>> midi.Gs_4 # G# octave 4 
56 
>>> midi.A_8 # A octave 8 
105 

>>> midi.NOTE_VALUE_MAP_SHARP[0] 
C_0 
>>> midi.NOTE_VALUE_MAP_SHARP[56] 
Gs_4 
>>> midi.NOTE_VALUE_MAP_SHARP[105] 
A_8 

打開MIDI文件與read_midifile()返回Pattern對象看起來像這樣(從實施例中採取的):

>>> midi.read_midifile('example.mid') 
midi.Pattern(format=1, resolution=220, tracks=\ 
[midi.Track(\ 
    [midi.NoteOnEvent(tick=0, channel=0, data=[43, 20]), 
    midi.NoteOffEvent(tick=100, channel=0, data=[43, 0]), 
    midi.EndOfTrackEvent(tick=1, data=[])])]) 

NoteOnEvent包含定時,MIDI數/俯仰和速度,其可以檢索:

>>> on = midi.NoteOnEvent(tick=0, channel=0, data=[43, 20]) 
>>> on.pitch 
43 
>>> midi.NOTE_VALUE_MAP_SHARP[on.pitch] 
'G_3' 

現在所有這些都很有趣,但是您並不需要將MIDI編號轉換爲音符,您只需要t o將其轉換爲http://virtualpiano.net/所使用的該筆記的鍵盤鍵。

中間C等於MIDI 60,這個音符對應於虛擬琴鍵盤上的第25個琴鍵,按下字母t激活。下一個音符Cs_5是MIDI 61,它是大寫字母T(<shift>-t)。從那裏你可以計算MIDI數字到支持的虛擬琴鍵的映射;那就是:

midi_to_vk = (
    [None]*36 + 
    list('[email protected]$5%6^78*9(0qQwWeErtTyYuiIoOpPasSdDfgGhHjJklLzZxcCvVbBnm') + 
    [None]*31 
) 

下一個問題,你將面臨被髮送的關鍵事件。請注意,在MIDI中,多個音符可以同時播放,或者可以在時間上重疊。這意味着您可能需要同時發送多個按鍵事件。

我不認爲你可以使用電腦鍵盤來處理速度。還有時間問題,但你說這對你來說不是問題。

0

檢查this問題第一個。這是關於如何模擬按鍵的一般想法,它可能看起來很多,但它只是一大串按鍵。然後,要將midi轉換爲鍵盤按鈕,您可以在筆記和鍵盤按鈕之間創建字典映射。

+0

我知道如何模擬按鍵。你正在談論的字典是問題。所有關於MIDI音符轉換的網站都有一張我不明白的鍵。喜歡:請注意#八度4是這個和那個midi數字,但實際上。 C-5,A#-2和其他'正常'音符不在虛擬鋼琴上,它有像C-61和A#-45這樣的音符,超過了任何網站的表格。 – alaswhu

0

我明白你真正需要的是一個MIDI音符編號轉換爲標準符號記的方式。

這裏是維基百科的一些元素:

... GM指定音符號碼69次A440,進而修復中C作爲音符數60 ...

(從MIDI - General MIDI

從MIDI音符數(d)轉換爲頻率(f)由下列公式給出:
F = 2 (d-69)/ 12 * 440赫茲

(從MIDI Tuning Standard - Frequency values

最後,來自C (musical note) - Designation by octave

Scientific designation |Octave name | Frequency (Hz) | Other names 
C4      | One-lined |   261.626 | Middle C 

Image of the C4 on partition and piano keyboard from wikipedia

所以C 是midi音符69,midi音符以半音(*)分隔。當你在一個八度有12個半音,你會得到ç在MIDI音符81,和著名的A440(MIDI音符69)是在科學記數法一個。

爲表

Midi note | Scientific notation 
60  | C4 
62  | D4 
64  | E4 
65  | F4 
67  | G4 
69  | A4 
70  | B4 
71  | C5 

一個例子,你會得到F♯在MIDI 66 ...

(*),它是音樂什麼叫做相等的氣質。 Midi允許更精細的音調定義,但它遠遠超出了這個答案。

+0

我認爲MIDI音符編號映射與python-midi模塊有所不同。如果我理解正確,這個模塊將MIDI 60映射到C_5而不是C_4。 '進口midi;打印midi.C_5'顯示60應該等於中間C.但是,如在https://en.wikipedia.org/wiki/C_%28musical_note%29#Designation_by_octave中列出的,中間C是科學名稱中的C4。也許我錯過了什麼?難道有些人可能會以八度音階-1開始,其他人則可能以八度音階開始? – mhawke

相關問題