錢 立
(四川職業(yè)技術學院 計算機科學系,四川 遂寧 629000)
虛擬化電子樂器是很有趣的音樂軟件,大家可在PC 或手機上使用,虛擬鋼琴就是其中一種。以前設計的虛擬鋼琴主要有這樣幾種:Flash 版,網(wǎng)頁版,手機端Android 或iOS 原生代碼開發(fā)版。因技術趨勢,F(xiàn)lash 不再推薦使用。網(wǎng)頁版鋼琴設計思路主要是按琴鍵時加載相應的音頻文件來發(fā)音。在這種方式下,若音頻文件較大,加載和播放較耗時,有時能明顯感覺到延時,不夠靈敏;若音頻文件過小,音效又較差。在手機安卓系統(tǒng)中可使用AudioTrack 來合成音調播放,但編程過程復雜。同時在安卓中設計鋼琴鍵盤也比HTML5 網(wǎng)頁界面復雜,控制起來也更麻煩。
Web Audio 是HTML5 中一個重要技術,使用該技術后可使得網(wǎng)頁版應用或復雜的網(wǎng)頁游戲具備華麗的音效,包括一些空間聲響效果。本文使用該技術結合JS 設計出的虛擬簡易鋼琴有很好靈敏度和音效。
Web Audio 采用了模塊化設計,這種模塊化設計提供了靈活創(chuàng)建動態(tài)效果的復合音頻的方法。一個簡單而典型的Web Audio 流程如下[1]:
(1)創(chuàng)建音頻上下文;
(2) 在音頻上下文里創(chuàng)建源( 輸入):例如〈audio〉、振蕩器、流;
(3) 創(chuàng)建效果節(jié)點:例如混響、雙二階濾波器、平移、壓縮;
(4)為音頻選擇一個目的地:例如你的系統(tǒng)揚聲器;
(5)連接源到效果器,對目的地進行效果輸出。
圖1 Web Audio 典型流程
本文設計的虛擬鋼琴使用振蕩器運算得到不同音調發(fā)聲。使用到Web Audio 相關API 如下:
AudioContext(音頻上下文)代表由音頻模塊構成的音頻處理圖。它控制其所包含節(jié)點的創(chuàng)建和音頻處理、解碼。使用其它接口前必需創(chuàng)建一個音頻上下文,一切操作都在這個環(huán)境里進行。
AudioNode(音頻節(jié)點)是一個音頻處理模塊,可以是音頻源、音頻輸出或中間處理模塊(比如音量控制器GainNode)。
AudioParam 代表音頻相關的參數(shù),比如一個AudioNode 的參數(shù)。它可以設置為特定值或值的變化,并且可以在指定的時間之后以指定模式變更。
OscillatorNode(振蕩器節(jié)點)代表一種隨時間變化的波形,比如正弦波形。類型是AudioNode,功能是音頻處理模塊,可以產(chǎn)生指定頻率的波形。
GainNode 用于音量變化,是一個AudioNode類型的音頻處理模塊,輸入后應用增益效果,然后輸出。
圖2 24 鍵鋼琴界面
設計的24 鍵鋼琴界面如圖2,這個界面使用HTML 和CSS 完 成[2]。 琴 鍵 樣 式key,白 鍵 樣 式whiteKey,黑鍵樣式blackKey,使用樣式疊加呈現(xiàn)出黑白琴鍵。
〈div class="main"〉
〈div id="key45" class="key whiteKey"〉〈/div〉
〈div id="key46" class="key blackKey"〉〈/div〉
…
〈/div〉
為了把琴鍵布置好,設置key 樣式為position:absolute;float:left;。然后使用JS 對每一個琴鍵設置樣式left 為不同偏移量,白鍵的寬度是手機屏幕橫屏時寬度的1/14,黑鍵寬度是白鍵的2/3,黑鍵高度是白鍵的一半。一定要給琴鍵賦id 值,便于定位鍵來確定發(fā)音頻率。
設計一個函數(shù)playSound(hz)來播放不同的音調。 hz 代表不同的音調,國際標準A 調是440.0hz。 這24 鍵琴音hz 用一個數(shù)組來保存,arrHz=[349.23,370.0,392.00,…][3]。
Web Audio 產(chǎn)生的音調波形主要有正弦波,三角波,矩形波,鋸齒波四種,但開發(fā)者可以自定義波型。這里設計了一種音效來模擬鋼琴發(fā)音后聲音逐漸消失的過程[4]:首先創(chuàng)建音頻上下文,指定音調為正弦波和頻率hz 后,再設置當前時間音量為0,0.01 秒后音量變到1,然后從當前時間開始播放音調,最后聲音在1 秒內慢慢減低直到停止。參看代碼如下:
function playSound(hz){
//創(chuàng)建OscillatorNode,表示一個周期性波形(振蕩),指定頻率后表示一個音調
var oscillator = audioCtx.createOscillator();
//創(chuàng)建GainNode,控制音頻總音量
var gainNode = audioCtx.createGain();
//把音量、音調和目的地節(jié)點關聯(lián)。audioCtx.destination 通常表示音頻渲染設備
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
oscillator.type=’sine’;
oscillator.frequency.value=hz;
gainNode. gain. setValueAtTime(0, audioCtx.currentTime);
gainNode. gain. linearRampToValueAtTime(1,audioCtx.currentTime+0.01);
oscillator.start(audioCtx.currentTime);
gainNode. gain. exponentialRampToValueAt-Time(0.001,audioCtx.currentTime+1);
oscillator.stop(audioCtx.currentTime+1);
}
在手機端上為了實現(xiàn)觸摸屏幕滑動琴鍵發(fā)音,則需使用JS 實現(xiàn)TouchEvent 事件的監(jiān)聽。主要 監(jiān) 聽 三 個 事 件 touchstart,touchmove,touchend。touchstart 事件也可看著是click 事件,可實現(xiàn)單個或多個琴鍵按下時發(fā)音。為了判斷觸摸從一個琴鍵移動到另一個琴鍵,需要保存上一個產(chǎn)生touchmove 事件的元素oldEle,同時要使用document.elementFromPoint(x,y)[5]來取得當前產(chǎn)生touchmove 事件的元素ele,后做進一
步判斷。關鍵代碼如下:
var oldEle = null;
keys[i].addEventListener(’touchstart’,han
dlStart,false);
keys[i]. addEventListener(’touchmove’, han
dlMove,false);
function handleStart(e){
e.preventDefault();
var touches=e.changedTouches;
var idx=e.target.id.substr(3,2);
play(arrHz[idx-45]);
e.target.style.backgroundColor="#9cf";
tmp=function(){
var obj=e.target;
if(obj.className=="key whiteKey"){
obj.style.backgroundColor="#ffe";
}else{
obj.style.backgroundColor="#444";
}
}//這里函數(shù)tmp 功能是用于還原琴鍵背景色
setTimeout(tmp,100);//此處琴鍵按下后背景
變色0.1 秒又還原
}
function handleMove(e){
var ele=document. elementFromPoint(e.
touches[0].clientX,e.touches[0].clientY);
if(oldEle==null){
oldEle=ele;
}else{
if(ele!=oldEle){
oldEle=ele;
}else{
return;
}
}
var idx=ele.id.substr(3,2);
playSound(arrHz[idx-45]);
}
為了使這個網(wǎng)頁應用運行時有效果,可使用Chrome 瀏覽器打開該HTML 頁面,再按F12 鍵切換到開發(fā)者狀態(tài),在右側開發(fā)者工具視圖中切換到手機視圖效果,這時鼠標放在頁面上會出現(xiàn)一個灰色的大圓點,這就代表觸屏??牲c擊左鍵表示觸屏tap 或按住左鍵移動表示touchmove。這樣就可以發(fā)出類似鋼琴的琴音了,按琴鍵或在琴鍵上快速移動都有敏捷的響應,發(fā)出的聲音效果也不錯。
如果想要直接運行在真實手機上,比如Android 系統(tǒng),主要有兩種方法。 一種是使用HBuilder 開發(fā)工具,連接上手機,自動安裝好HBuilder 基座后,編寫好網(wǎng)頁應用立刻就能在手機上運行出效果。另一種是在可開發(fā)Android 程序的Eclipse 或Android Studio 中創(chuàng)建Android應用,在主Activity 中加入WebView 組件(全屏效果),然后通過WebView 組件加載本地HTML 網(wǎng)頁,并允許JS 執(zhí)行。這兩種方法對于Android 系統(tǒng)最終均可生成apk 文件用于正常安裝運行。
以往設計的虛擬鋼琴通常是加載音頻文件發(fā)音,隨著Web Audio 技術的完善提高,我們可采用其技術通過波形和頻率來產(chǎn)生特定的音調和音效。 使用HTML5 和CSS 設計鋼琴界面,使用Web Audio 與JS 結合實現(xiàn)發(fā)音效果,這能較容易地設計出響應靈敏和漂亮音色的虛擬鋼琴。本文案例應用在教學過程中,一方面提高了學生開發(fā)興趣,另一方面也拓展了知識,這個綜合性案例有很好的教學效果。