開場不囉嗦!先來段彈奏卡農的影片,就知道今天要介紹的東西,能有什麼樣的效果:
好吧!這不是烏克麗麗,因為它沒有弦,只是因為它的尺寸接近烏克麗麗,就叫它電烏克麗麗,總之名稱不重要 … XD
積木組裝
這把電烏克麗麗,主要使用了三個觸碰感應器,搭配主機上的五個按鈕,因此可以彈奏 40
個音階,組裝方式可以參考 ElectricUkulele.lxf,或 線上觀看組裝過程,成品圖如下:
其實大部份的零件,都是拿來做造型了,控制發音的原理很簡單,左手三個觸碰感應器按下與否會有 8
個狀態,每個狀態下可搭配主機按鈕發出 5
個音階,如果以頻率 261.626
的 C(Do)開始,可以發出的基本音階如下圖:
左下方的 EV3 就是對應的方向,主機按鈕依左、中、右、上、下的順序,相距都是一個半音,上圖中每個八度裏沒有畫出來的音階,就是半音的部份了,也就是相當於鋼琴的黑鍵部份。
40 個判斷分支?
觸碰感應器的按鈕若未按下,輸出值為 0
,按下則為輸出值 1
,依上頭的規劃,三個觸碰感應器的值組合會有 000
、001
、010
、011
、100
、101
、110
、111
,主機按鈕依左、中、右、上、下的順序,輸出值分別為 1
到 5
。
按照程式設計邏輯,要不就是判斷觸碰感應器的八個狀態值,再去判斷主機按鈕的五個狀態值,要不就列出 0001
、0002
、0003
、0004
、0005
、0011
、0012
… 共 40
個狀態值,總之,就是有 40
個判斷分支,程式很簡單吧!
我可不想這麼做,40
個判斷分支實在太可怕了,而且如果我要再多一個觸控感應器,讓電烏克麗麗可以發出 80
個音階,我又得再多加上 40
個判斷分支,一定有別的方法!
十二平均律
稍微摸過樂器的,可能會知道 十二平均律,簡單來說,對於一個八度的音程,可被平均切分為十二等分,每個等分是一個半音的音程,例如 C 大調的話,就是 C、C#、D、D# … 一直到下個高度 C 共八個半音。
對這個電烏克麗麗的設計,重要的是知道,這十二等分的劃分,並不是用等差級數,而是用等比級數來劃分,每個半音間的音程,有著 2
的 12
次方根的倍數關係,約為 1.059463
,例如 C 的頻率為 261.626
,那麼下個半音 C# 就是 261.626 * 1.059463
,也就是 277.183
,再下個半音 D 就是 277.183 * 1.059463
,也就是 293.665
,依此類推。
因此,只要一個簡單的算式,就可以從觸碰感應器與主機按鈕的輸出值,計算出要發出的音階頻率,如果要多一個觸碰感應器,也只要在算式中多個變數就可以了,這比硬是用程式邏輯來蠻幹有效率多了,嗯 … 套句程式界的老生常談 … 領域知識(Domain knowledge)很重要 … XD
程式撰寫
主要的程式流程很簡單,就是等待主機按鈕按下,取得觸碰感應器與主機按鈕輸出值,轉為頻率令主機發出音階、在主機按鈕放開後停止發音:
觸碰感應器與主機按鈕輸出被封裝為一個 KeyState 的自訂 Block,因此它有四個輸出值:
當然,下個 ToHz 自訂 Block 才是重點:
三個觸碰感應器的值會被當成二進位組合,算出 0
到 7
的值,這就是 a + b * 2 + c * 4
算式的作用,這個值與主機輸出值結合,01
表示未按下觸碰感應器下,按下主機左邊按鈕、02
表示中間按鈕、03
是右邊按鈕、04
是上邊按鈕、05
是下邊按鈕,接下來,11
是按下一個觸碰感應器下,按下主機左邊按鈕、12
表示中間按鈕、13
是右邊按鈕、14
是上邊按鈕、15
是下邊按鈕,依此類推,因此,你要做的值轉換關係是:
01 -> 1
02 -> 2
03 -> 3
04 -> 4
05 -> 5
11 -> 6
12 -> 7
13 -> 8
14 -> 9
15 -> 10
21 -> 11
22 -> 12
23 -> 13
24 -> 14
25 -> 15
略 ...
也就是說,右邊位數每 5
進位,這就是算式 (a + b * 2 + c C* 4) * 5 + d
的作用,對於多變數的算式,EV3 的 Math 方塊可以設定為 ADV,也就是進階設定,直接輸入算式,減少方塊的佔用面積。
頻率起算的部份,因為 EV3 的 Sound 方塊可以設定的頻率範圍為 250
到 10000
,因此就使用 261.626
的 C 頻率做起算。
那麼,就可以來段卡農了,只是,這樂器的按鈕組合會不會太難記了?嗯!熟能生巧!多練幾次就好啦!不過,還是有取巧的方式,吉他或烏克麗麗不是有 Tab 譜嗎?就是那種直接標示手指位置的譜,上頭一開始的卡農,我也是寫了個類似 Tab 譜的東西來彈的,連我家六歲的小女兒都彈的出來 … XD