2011-03-20 142 views
5

是否有允許將MIDI(或WAV)文件轉換爲<frequency, duration>列表的任何腳本/軟件/算法,以便我們可以重放此聲音的「圖像」文件,例如,通過C#中的System.Console.Beep(frequency, duration)函數?將MIDI或WAV文件轉換爲頻率和持續時間數組

+2

你已經問過兩個極其不同的問題。MIDI和WAV是完全不同的,不僅在格式上,而且在整個音頻存儲方式上。 MIDI將音頻存儲爲一系列音符,因此提取頻率和持續時間對是微不足道的(我不知道有任何特定的軟件可以做到這一點;我已經寫了自己的做法,以非常冒險的方式做到這一點) 。 WAV是數字樣本,因此您需要頻率分析軟件來獲取筆記數據。這是可能的,但不是100%準確和完全不同的水壺。那你想要哪個? – mgiuca 2011-03-20 07:28:42

+0

至少,如何做的MIDI文件(但也告訴我WAV的原則,因爲我很好奇,我讀的地方FFT不足) – anonymous 2011-03-20 07:32:31

+0

這真是一個很有趣的想法。大概你拿WAV文件,轉換到頻域(例如FFT),然後應用一個psycoacoustic模型來選擇一個人會聽到的單一「嘟嘟聲」。排序相當於一個photoshop「印象派」過濾器的音頻...... – 2011-03-20 07:48:38

回答

2

您需要將MIDI,WAV或其他聲音文件轉換爲原始音頻樣本。然後,對於連續的樣本塊(通常每個塊重疊50%),應用窗函數(例如Hanning),然後應用FFT,然後獲取FFT輸出箱的大小,然後對於音頻,通常需要20 * log10這個幅度得到一個dB值。

+1

+1,這對於WAV很好,但不要打擾這種MIDI方法。如果您在MIDI中有某些內容,請不要合成它並將其讀回來。 – Brad 2011-03-20 07:48:55

+0

@Brad:這取決於您是否只需要音符信息(當然,您可以直接從MIDI數據中獲得這些信息),還是需要完整的音頻頻譜 - OP的問題對於他想要什麼樣的「圖像」非常模糊。 – 2011-03-20 07:59:14

+0

請注意,此FFT方法將給出聲音中的近似頻譜頻率,而不是音樂中的音符或音高頻率。持續時間也將被量化爲FFT窗口的時間步長,這可能是也可能不是精確測量任何實際音符或音調突發的長度。 – hotpaw2 2011-03-20 17:37:40

1

Paul R對WAV的解釋很好。

對於MIDI,您將不得不選擇一個音軌並讀取MIDI數據。您如何決定哪條賽道由您決定,但您只能挑選一條賽道,因爲您一次只能使用您的方法從PC揚聲器中獲得一個「音符」。

C#MIDI教程:http://www.codeproject.com/KB/audio-video/MIDIToolkit.aspx

一旦你上讀了,你應該知道如何閱讀的MIDI文件從那裏,你可以把這一對頻率和持續時間。持續時間取決於節奏和音符持續的節拍數量,音高將取決於音符編號及其相應的頻率(根據equal temperament)。 (如果你想變得非常瘋狂,你甚至可以處理交替調音,但現在我不擔心它。)

另外,我相信NAudio has some MIDI classes for reading files,但它們可能不完整。當我們變得瘋狂......如果你能夠有效地進行線程化(這將是幾乎不可能的,我會想象,但是...),對於WAV播放,你可以使用PWM to drive the PC speaker and emulate PCM audio playback。我記得一些舊的DOS games from Necrobones曾經這樣做,並且有一個Windows 3.1的驅動程序,在我的33MHz筆記本電腦上運行良好,可以用於平時的點擊和點擊。儘管從託管框架(或者甚至在沒有實時優先級的Windows內)這種方法可能非常困難。

2

對於MIDI,您必須自己解析文件(我已經完成了,我推薦以下兩個參考文件:onetwo),或者獲取MIDI工具包。我不知道任何.NET,但here is a Google search

一旦你明白了,它應該相當容易。使用工具包讀取MIDI文件,這會給你一套曲目。每個軌道包含一系列事件,每個事件都具有相對於先前事件的時間戳。一個事件可以是「注意到」,「註銷」,或者您可能不關心並且可以忽略的數百個其他事件之一。只需查找「註釋」和「註銷」事件即可。通常,每個音符是一個「音符開」(具有一定的音高和速度,這是音量),隨後是一段時間的「音符關」(音高相同,速度爲0)。你可以用這個信息來構造一個四重音符(開始時間,持續時間,音調,速度)的音符表,其中開始時間是「音符開啓」事件的時間,持續時間是時間差在「音符開」和「音符關」之間,音高/速度是「音符開」的音高/速度。您可以使用this formula將音高轉換爲頻率。

至於WAV/MP3/AAC/OGG,所有這些都與Paul在他的回答中提出的技術相同。