搖滾吧HTML5!Jsonic超聲波前端交互!


  前些年吹過一陣canvas制作html5游戲的東風,相信不少同學重溫了一把高中物理課本上的牛頓定律。時光如梭,你是否還記得牛頓定律后面一章的各種機械波的物理定律?環視四周,光纖、wifi、藍牙、廣播都有波的身影,可以說機械波橋接了信息時代。Jsonic作為前端的音頻交互框架,也有利用聲波進行數據傳輸的接口,在介紹API之前,先分享一些web audio原生編碼的干貨。

  讀了這系列前兩篇博文搖滾吧HTML5!有聲前端交互!(一)搖滾吧HTML5!有聲前端交互!(Hello, Jsonic!)的同學,應該已經能夠使用web audio產生一個特定頻率的聲波了。所謂的超聲波,就是頻率超過20000hz的聲波,正常成人人耳能接收的聲波范圍是20-20000hz。20hz以下的次聲波因為頻率和人體一些器官相近,可能對人體造成損傷,所以不建議使用。這么一看,發出超聲波就很簡單了,代碼如下,使用oscillaor節點。

var context = new webkitAudioContext(),
    osc  = context.createOscillator();
osc.frequency.value = 20000;
osc.connect(context.destination);
osc.start(0);

  這里有一點值得注意,oscillator節點的start方法只能調用一次。一旦調用了oscillator的stop方法,想要再發出這個頻率的聲音,就只能再創建一個新的對象了。在web audio中,我們還可以使用gain節點配合oscillator的方法,定期發出指定的聲波。你可以把gain節點理解為一個信號強度調節器,通過設置gain.gain.value的值,可以控制信號的強弱。這個值取值范圍是0~1。玩過音箱,效果器這些東西的同學應該就比較好理解了,其實web audio可以串聯各種效果的節點。(下圖僅供參考)

   

  回到代碼的世界:

var context = new webkitAudioContext(),
    gain = _ctx.createGain(),
    osc  = context.createOscillator();
osc.frequency.value =20000; 
gain.gain.value=0;
osc.connect(gain); 
gain.connect(context .destination); 
osc.start(0);
gain.gain.setValueAtTime(1,1);
gain.gain.setValueAtTime(0,2);

  通過以上代碼,可以在1-2秒這個時間區間內發出一個20000hz的超聲波信號。這里調用setValueAtTime方法改變gain節點的值,波形變化過程如下圖所示。gain節點有各種不同的方法,這些方法使信號強度到達預設值有不同的變化過程,讀者可自行查閱web audio的API。

  通過gain節點控制信號和直接使用oscillator的start和stop方法控制信號各有利弊,具體使用大家可自行考慮。有了信號源,接下來就是接收的問題了。很多文章都介紹過html5的音頻可視化,其核心就是通過analyser節點獲取數據。這里簡單羅列下analyser節點獲取數據的幾種方法。

//通過浮點數組獲取時域數據
var data = new Float32Array(analyser.fftSize);
analyser.getFloatTimeDomainData(data);

//通過浮點數組獲取頻域數據
var data = new Float32Array(analyser.fftSize);
analyser.getFloatFrequencyData(data);

//通過 Uint8數組獲取時域數據
var data = new Uint8Array(analyser.fftSize);
analyser.getByteTimeDomainData(data);

//通過 Uint8數組獲取頻域數據
var data = new Uint8Array(analyser.fftSize);
analyser.getByteFrequencyData(data);

  時域信號和頻域信號可以通過傅里葉變化互相轉換,Jsonic選擇的是unit8數組獲取頻域信號,以下是獲取頻域數據的代碼。

var ctx = new webkitAudioContext();
navigator.webkitGetUserMedia({
    audio:{optional:[{echoCancellation:false}]}
},function(stream){
    var analyser = ctx.createAnalyser(),
        _input = ctx.createMediaStreamSource(stream),
        data = new Float32Array(analyser.fftSize);
    _input.connect(analyser);
    analyser.getFloatFrequencyData(data);
},function(e){});

  這里的data數組獲取的是所有頻率的數據,那么怎么找到對應的頻率數據呢?又要上物理課了。。。。。。這里要用到 奈奎斯特定理,不懂的同學可以直接看公式B=2W。通過audioContext節點sampleRate屬性,我們可以獲取在當前web audio上下文的采樣率(一般是192000),那么通過奈奎斯特定理,這個采樣率/2就是我們能采集到的信號頻率的范圍了。上面我們采集到的data數組長度默認是1024。以192000的采樣率為例,data數組就是把0-96000hz的聲波數據均分成1024個頻率存儲。到這里我們就能獲取到頻率數據了。雖然采樣范圍很廣,但是不同設備通過oscillator節點能產生的聲波的頻率極限不同,我之前用iphone5測試的時候在22500hz左右。

下面簡單介紹下怎么用Jsonic收發超聲波數據,更多信息可以自行搗鼓jsonic.net

  在jsonic之前的版本中,使用的是峰值分析法解碼數據。最近發布了新的版本,使用的是波形分析法,使用了新的Band對象。無論接收還是發送端,在Jsonic中都要創建一個band實例。

var band = new Jsonic.Band();
band.initDefaultChannel();

接收端 demo (點擊start按鈕后,需要授權瀏覽器使用麥克風)

navigator.webkitGetUserMedia({
    audio:{optional:[{echoCancellation:false}]}
    },function(stream){
        _input = band.AudioContext.createMediaStreamSource(stream);
        band.listenSource(_input);
        band.scanEnvironment();
},function(e){});

發射端 demo (功放,發射輸入框中的文字)

band.send('Hello Jsonic',function(){
    //call back
});

最后附上github地址 https://github.com/ArthusLiang/jsonic 走過路過,給個star :),同時也期待前端大神加盟。

轉發請注明出處http://www.cnblogs.com/Arthus/p/4281442.html

 


免責聲明!

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



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