其實音樂音效這個命題本身沒什麼好研究的。
Unity3D提供了豐富的結構和使用方式,足夠使用了。
但是我有一些小小的想法和需求,一般的Unity資料並沒有給我答案。
- 一個是容量要小。MP3、OGG的高音質壓縮一分鐘一M多,多放幾首背景音樂就頂不住了。
- 一個是資源和主程式分離,方便更新,別和我提AssetBundle,這東西的平臺不相容性,完全是在增加麻煩。
- 還有就是想要一個示波器
像這樣的就行了。
問題1、最小不過MIDI,MIDI是樂曲的原始資訊,本地合成,1M多MP3不過一分鐘,MIDI錄一個小時也用不到1M。
這個問題就決定用MIDI來解決。
但MIDI的音色庫也不小,一查動輒幾十兆上百兆的音色庫。
就簡單的瞭解了一下MIDI的發展過程。
其實下面的文字我完全不知道他們在說什麼,只是抄來的
1981年產生,作為一種裝置連線標準,像USB那種東西。不過是專門為音樂而設計的。
1991年形成標準,制定了128種標準樂器。
第一塊音效卡 sound blaster 使用FM(頻率調變)技術合成MIDI聲音。
FM這種技術不需要什麼記憶體,我就發現了這一點。
後來記憶體不是問題了,就發展出了波表合成技術GM,每種樂器的音色都是錄製而來的,每個樂器都要錄很多,再配合規則合成。
波表就比較費記憶體了,windows自帶的那個波表有4M,網上很容易找到幾十上百兆的波表
MIDI只能產生樂器效果,對於挑剔的耳朵來說,還是用OGGMP3之類能完美模擬聲音的方式吧。
FM的聲音效果按今天的標準來說可能有些慘不忍睹,管他呢,能提供MP3 百分之一的容量,還沒有什麼副作用。
各位自取所需吧,我反正是打算做點8bit風格的東西,FM夠用。
那我們解決這個容量問題的關鍵就是找一個能用FM技術播放MIDI的東西。
然後就找到了http://forum.unity3d.com/threads/unitysynth-full-xplatform-midi-synth.130104/
FM播放所需的資料只有幾百位元組。
它提供了播放MIDI所需的一切,可以用FM技術合成,也可以用波表技術合成。
最關鍵的,它提供了一個例子,讓我知道Unity怎麼用DSP混音,這樣最後一環就通了,可以用DSP去播放合成出來的聲音。
問題2、資源和主程式分離
由於c#synth是完全從聲音合成做起的,所以他不依賴任何庫,這為跨平臺提供了得天獨厚的條件,可以說本來就是跨平臺的。
我們找到的那個方案有一些無傷大雅的小bug,我已經修改了可以跨平臺了。我還放了一個webplayer版本。
http://moshan.co/game?id=53,你可以開啟看一看,內建了幾十首midi,連主程式也只有200K
ogg雖然解碼器也是開源的,但是我並沒有找到c#的版本,如果要用ogg去做跨平臺的播放,工作量可能不小。
Wav雖然不開源,但是wav pcm方式儲存時格式非常簡單,很容易實現。問題是wav容量比較尷尬,做音效可以,做音樂可捨不得用wav存。
問題3、示波器
這個問題其實我也不懂,硬著頭皮搞出來的。
我就大概知道頻率分析要用到傅立葉變換。
然後剛好前面學會了unity怎麼用DSP混音。
那就加一個DSP混音,但是不改變聲音,僅用來讀取聲音。
然後把每次得到的聲音時域值域輸入,拿傅立葉變換計算一下。就得到頻域值域的輸出。
然後把輸出按我們想要觀測的頻率取出幾個值。。。
好吧,其實時域值域頻域我都不知道我到底理解對了沒有,如果我前面亂講,當我沒講過,這些年也沒怎麼接觸過傅立葉變換啊。
反正最後弄出了這麼個效果
拿到這串數字做什麼效果都可以,我只是簡單的用GUI.Button 畫了些變換的棍子。
最後,附上GITHUB原始碼地址
https://github.com/lightszero/BlockFun/tree/master/unity/MidiPlayer