【Win 10 應用開發】MIDI 音樂合成——樂理篇


針對 MIDI 音樂的 API ,其實在 Win 8.1 的時候就出現。在UWP中采用了新的驅動模式,MIDI 消息傳遞更加高效。

首先得說明的是,UWP 的 MIDI 相關 API 不是針對 MIDI 文件的,而是針對 MIDI 設備的,所以它不具備保存 MIDI 文件的功能。當然,如果你想把 MIDI 消息存為音頻文件,完全可以自己一個字節一個字節地寫入。MIDI 文件分為兩個數據塊——頭部和音軌。頭部主要描述音軌類型(單軌或多軌),包含軌道數量,以及計時方式。

MIDI 有兩種方式來描述音符時值:

1、Timing Clock:單個四分音符(常規是每四分音符為一拍)的“脈沖時鍾數”(PPQ),時間單位Tick,一般為24的倍數。

2、幀率。這個跟視頻有點像,比如24幀,30幀等。

計時方式用兩個字節表示(16位),如果最高位為0,表示用Tick方式來描述,剩下的15位表示Tick值;如果最高位為1,則表示幀率。

比如,如果用Tick方式表示(常用),第16位必須為0,即 0111 1111  1111 1111。

MIDI 文件除頭部外,剩下部分都是音軌數據。每個音軌由一系列事件組成。事件就是MIDI指令。MIDI 文件之所以體積小,是因為它不存儲音頻數據,只存儲指令。比如 Note on 開始播放某個音符,Note off 停止播放某個音符。每個事件都由兩段組成:

<delta time><event data>

Delta time 指事件的時間偏移量,它是相對於前一個事件而言的,當然,如果是軌道中的第一個事件(或者是元數據事件),delta time 可以是0。常用的是tick計時方式,比如,文件頭中指定每個四分音符的時值為96,那么,假調事件A播放中音1(C),事件B停止播放中音1,如果這個中音1是四分音符,即時值為1拍,兩個事件可這樣排列:

<0><note on 60><96><note off 60>

60中音1的編碼,這個老周后面會說,也就是B事件要在A事件后面,相隔時間為96,1拍。如果是八分音符呢,就是48(半拍)。

<0><note on 60><48><note off 60>

 

好了,關於 MIDI 文件的信息就說到這里,有興趣的話,你可以到 midi.org 官方網站去查看相關的規范。老周寫了一個讀寫 MIDI 文件的通用類,功能還未完尚,僅供參考。下載鏈接在這里

 

=====================================================

下面咱們說正題。

UWP 中的 MIDI API 是用於與 MIDI 設備通信的。其實總的來說也就兩種設備:輸入/輸出。輸入設備一般來說也就是 MIDI 鍵盤了。這個我們一般人用不上,買一個的話也不便宜,起碼要幾百大洋。輸出設備可以是專門的MIDI聲卡,當然,我們一般的聲卡也可以。普通聲卡支持MIDI 的通用標准,缺點是音色不太真實。專業聲卡再配上軟音源就可以模擬出更多樂器的音色,而且質量也高。軟音源也不便宜,買一套大概也要一千大洋。

本篇咱們先不說 API 怎么用,很簡單,因為微軟都封裝好了的,直接發送 MIDI 消息就行了,或者從外接的 MIDI 鍵盤中接收 MIDI 消息。但是,前提是你得有一點樂理知識。要求不高,能看懂簡譜的話,就可以了。

 

簡譜頭部

在簡譜上,標題、副標題這些就不多說了,都能看明白的。在簡譜頭部,我們主要了解三個標記:

1、調號。比如我們看到許多簡譜上會標注 1 = C,意思是中音1的發音是鋼琴鍵盤上的【中央C】鍵(白鍵)。調號不理解也無所謂,其實不影響MIDI編程,我們就不需要弄得太復雜了,尤其是大調小調的區分,除非你對音樂有興趣,可以研究研究。反正就是調越高聲音越尖銳,調越低聲音越柔和。所以小調一般很適合民歌。

2、拍號:常用的是 4/4,分子為4,表示每四拍為一小節;分母為4,表示一個四分音符為一拍。這是最常見的。比如這樣:

前面部分是調號,緊跟着是拍號。

如果是,2/4,表明每兩拍為一小節,四分音符為一拍。

3、節奏(節拍):表示每分鍾多少拍(BPM)。常見的節奏為120。

表示一分鍾 120 拍,所以,每拍的時長為 0.5 秒。

如果是60,表明一分鍾60拍,即一秒一拍。

 

實際上,決定曲子速度的不是拍號,而是節奏。120 的曲子速度自然要比 60 的快。拍號只是確定每個音符的相對時值,標准是四分音符為1拍,那么八分音符就是半拍,十六分音符就是1/4拍,三十二分音符就是1/8拍了。總之都是二次方的,而且分的越小時值越短。

前面提到MIDI文件有 Tick 和幀率兩種計時方式,其實計時方式也不會影響曲子的速度(時長),就好比2分鍾長的視頻,你把幀率從 30 幀改為 15 幀,但視頻長度依然是 2 分鍾,只是變得不太流暢而已。MIDI 中也一樣,速度是由節拍映射(Tempo map)決定的。不同的是,我們簡譜中用的是 BPM(每分鍾多少拍),而MIDI中用的是微秒,比如,BPM=120,即0.5秒一拍,換算為微秒就是 500000了。

 

小節

上面咱們提到過,4/4表示每四分音符為一拍,每小節一拍。那小節是啥?在簡譜上,用小節線(豎線)來划分小節。請看下面例子。

上面例子中有兩個小節,按照拍號的規定,每小節必須是四拍,第一個3是兩拍,第二個3是兩拍,加起來正好是四拍。所以后面緊跟一條豎線,這根線就是小節線。第二個小節中,中音5是一拍,中音2是一拍,緊接着的中音3、1下面都有一橫線,是八分音符,各半拍,加起來正好一拍;最后的低音6是一拍,合起來也是四拍。

 

再看一個例子。

注意看拍號,2/4表示每四分音符為一拍,但每小節是兩拍。比如第一小節,中音1、中音2都是四分音符,各一拍,共兩拍,所以構成一個小節。

 

音符

我們剛剛在簡譜上看到的1234567,就是音符,當然這是簡譜上的表示法,這種表示法,容易識別。在五線譜中,音符是用“蝌蚪文”來表示的,不容易分別,也不好懂。

順便說說唱名和音名。這兩個東西,很多時候都會搞混。所謂唱名,就是你用嘴巴唱出來的時候發的聲,就是

dol  re  mi  fa  sol  la  xi

對應的音符就是 1 2 3 4 5 6 7。這個應該不難,小學生都懂。

音名就是鋼琴鍵盤上那些字母,與唱名對應的是 C D E F G A B。

中國很多樂器(尤其是吹管類)的基本音域都在 1 2 3 5 6 這幾個音上,那是因為我們古代的定音方式為“宮,商,角,徽,羽”,有的說是“宮,商,角,徴,羽”,對應的大約是1 2 3 5 6,古人是用“三分損益”法計算音階的。因此,許多民樂都沒有 4 這個音(3和4的音程是半音),比如,巴烏就是個典型。 笛子和洞簫雖然有 4 這個音(放開全部音孔,八孔簫要按住半音孔),但發聲相對較弱。其實,像巴烏(葫蘆絲)這些樂器也可以通過接中音5以下的音孔來調節出 4 的音,但也是比較弱的。

 

十二平均律

音階划分方式很多,比如中國古代有“五度相生”法,五度指純五度,這個很復雜,老周也說不清楚,不過,我可以總結出一句不太靠譜的話——純五度的總音程為 3.5 個全音(三個全音,一個半音)

其他的計算方式不多講,因為 MIDI 的音階用的是十二平均律,這是世界普及的,琴鍵上用的也是十二平均律。其實,十二平均律是中國人發明的,在明朝的時候就出現了,只是當時樂器生產工藝限制,沒有人願意接受這種方式,結果讓西方人搶了頭功。

十二平均律是以每【半音】來划分的,因此,它可以包含12個音:

1、1#、2、2#、3、4、4#、5、5#、6、6#、7

對應的音名為

C、C#、D、D#、E、F、F#、G、G#、A、A#、B

其中,3和4之間的音程是半音,前一八度的7與后一八度的1之間的音程是半音,其余為全音,比如1和2之間是全音,所以,在1和2之半加一個 1#,表示在1的基礎上升半音,因此,1# 和 2b 是同一個位置,1升半音就是 1#,2 降半音是 2b。

文字是說不清楚的,看看這個圖你就懂了。

 

 不管白鍵還是黑鍵,兩個鍵之間的音程都是半音,你會看到,3 和 4 之間沒有黑鍵,因為 3 和 4 之間的音程就是半音。故 12345 就是所謂的純五度,因為它們的總音程就是 3.5 個全音。

再看一張更大的圖。

這樣你就看到規律了,一個八度的鍵排序是這樣的:

      黑              黑                       黑              黑                黑                        ……

-------------------------------------------------------------------------------------------------------------------

白            白              白      白             白               白                 白             ……

故而,3和4之間是兩個白鍵,7和1之間是兩個白鍵,因為它們的音程都是半音。

將其替換為十二個音符,就是:

    1#       2#              4#        5#        6#            ……

-------------------------------------------------------------------------------

1         2          3   4          5          6          7       ……

 

 介紹完音符,咱們還要了解音符的時值,所謂時值,就是音符的相對時間長度。

按照時值不同,可以分為以下幾種:

1、全音符。標准情況下是四拍,表示方法為 X - - -。

2、二分音符。標准情況下是二拍,表示方法 X -。

3、四分音符。一拍,表示方法 X。

4、八分音符。半拍,表示方法 

5、十六分音符。四分之一拍,表示方式 

6、三十二分音符。八分之一拍,表示方式 

……

后面就不再分了,時值太短了,你也唱不出來。

當然,也有比較特殊的,比如,三拍時值的音符,也可以表示為 X - -。

 

好了,只要有了上面這些基本知識,就可以開始 MIDI 編程了。下一篇老周就說說如何向聲卡發送 MIDI 消息。本篇就扯到這兒了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM