国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

努力翻譯一篇中文最友好的,Web Audio API的使用相關(guān)的文章

caikeal / 1677人閱讀

摘要:前言本文翻譯自上的利用,這是中的的一個(gè)入門教程。原文是英文,但有日本同志翻譯的日文版。這是為了提供一個(gè)基本的低音増幅效果在這個(gè)例子中可以設(shè)定過(guò)濾器的種類,周波數(shù),甚至的值。如果是過(guò)濾器的話,可以提供一個(gè)比指定周波數(shù)低的低音増幅。

前言

本文翻譯自MDN上的《Web Audio APIの利用》,這是HTML5中的Web Audio API的一個(gè)入門教程。原文是英文,但有日本同志翻譯的日文版。我更熟悉日文,所以主要根據(jù)日文版翻譯成簡(jiǎn)體中文,也會(huì)對(duì)照英文版的。

Web Audio API的使用

Web Audio API提供給你一個(gè)簡(jiǎn)單卻強(qiáng)大的機(jī)制,你可以利用它去實(shí)現(xiàn)與操作web應(yīng)用內(nèi)的音頻內(nèi)容。通過(guò)它,在網(wǎng)頁(yè)中你也可以進(jìn)行混音、音效、平移等各種復(fù)雜的音頻處理功能的開發(fā)。這篇文章主要想通過(guò)兩個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明Web Audio API的基礎(chǔ)使用方法。

Web Audio API并不是替代

Web Audio API的一個(gè)強(qiáng)大之處是它沒有嚴(yán)格的[發(fā)出聲音的數(shù)目的限制]。例如,一秒內(nèi)可以同時(shí)發(fā)出32個(gè)聲音或64個(gè)聲音,但這并不是上限。CPU的處理能力足夠的話,1000多種聲音也可以不經(jīng)過(guò)壓縮直接播放。如果這樣發(fā)展下去的話,幾年之后的中高端聲卡的負(fù)荷會(huì)大大降低的吧。

PS:補(bǔ)充點(diǎn)背景知識(shí),這里提到的32,64指的是復(fù)音數(shù)。復(fù)音數(shù)指MIDI樂曲在一秒鐘內(nèi)發(fā)出的最大聲音數(shù)目。關(guān)于復(fù)音數(shù)和MIDI樂曲可以百度一下。聲卡硬件會(huì)限制復(fù)音數(shù),部分軟件使用CPU實(shí)現(xiàn)聲音播放的也會(huì)限制復(fù)音數(shù)。但理論上只要CPU處理能力夠強(qiáng)復(fù)音數(shù)是不受限的。所以上段提及Web Audio Api是軟件,但它沒有復(fù)音數(shù)限制,所以說(shuō)到只要CPU處理能力夠強(qiáng),未來(lái)或許能夠降低對(duì)中高端聲卡性能的需求

例子

為了展示W(wǎng)eb Audio API的用法,我們編寫了一些例子,這些例子會(huì)不斷地增加更新。請(qǐng)大家發(fā)揚(yáng)開源
精神為項(xiàng)目添加用例或者提出更好的改善意見!

PS:這些例子最好在最新版chrome中運(yùn)行

首先介紹一下 Voice-change-O-matic 。這是一個(gè)有變聲及聲音可視化功能的網(wǎng)頁(yè)應(yīng)用,且有一些變聲效果與可視化效果可供選擇。雖然這個(gè)應(yīng)用還有許多可以改善的地方,但也不失為綜合使用Web Audio API的許多功能的一個(gè)好例子。(可以在這里運(yùn)行 Voice-change-O-matic)

PS:上面的這個(gè)例子我運(yùn)行沒效果啊,不知道怎么玩
*PS:感謝vino24補(bǔ)充的,該例子需要https,在chrome下可運(yùn)行

為了理解Web Audio而編寫的另一個(gè)例子就是這個(gè)Violent Theremin。這是一個(gè)簡(jiǎn)單的應(yīng)用,它允許你通過(guò)鼠標(biāo)指針的移動(dòng)來(lái)改變頻率和音量。另外,鼠標(biāo)移動(dòng)過(guò)程還有迷幻光彩的視覺效果。(Violent Theremin的源碼在這里)

基本思路

備注:下面列舉的大多數(shù)的代碼片段都在Violent Theremin中有使用。

Web Audio API的架構(gòu)設(shè)計(jì)使得它能夠輕松實(shí)現(xiàn)模塊路由,其中包括對(duì)上下文中的音頻內(nèi)容的操作。基本的音頻編輯可以使用audio node進(jìn)行。但這些節(jié)點(diǎn)相互可以連接起來(lái),可以構(gòu)成一個(gè)節(jié)點(diǎn)圖。多個(gè)音源或者不同種類的頻道最終都可以對(duì)應(yīng)到一個(gè)上下文中。這樣模塊化的設(shè)計(jì)是為了提供足夠靈活的特性以便開發(fā)可以動(dòng)態(tài)改變效果的復(fù)雜的音頻編輯功能。

audio node有入口和出口,多個(gè)節(jié)點(diǎn)構(gòu)成類似鏈表一樣的結(jié)構(gòu)。從一個(gè)或者多個(gè)音源出發(fā),經(jīng)過(guò)一個(gè)或者多個(gè)處理節(jié)點(diǎn),最終輸出到輸出節(jié)點(diǎn)(輸出終端,一般是揚(yáng)聲器)。(如果有需求的話,也可以不指定輸出節(jié)點(diǎn)。例如,想把音頻數(shù)據(jù)用圖表的形式展現(xiàn)的場(chǎng)合等。)web audio的一個(gè)簡(jiǎn)單的典型的流程類是下面這樣子:

創(chuàng)建AudioContext對(duì)象

在AudioContext對(duì)象內(nèi)設(shè)置音源,例如

創(chuàng)建effect node(效果節(jié)點(diǎn))。例如reverb, biquad filter, panner, compressor(這些都是音頻特效)

選擇音頻的最終輸出節(jié)點(diǎn)。例如,你的電腦的揚(yáng)聲器

音頻經(jīng)過(guò)效果節(jié)點(diǎn)處理后,然后輸出到下一個(gè)節(jié)點(diǎn),這些節(jié)點(diǎn)連接起來(lái)

創(chuàng)建AudioContext對(duì)象

首先,為了構(gòu)建audio節(jié)點(diǎn)圖,我們首先要?jiǎng)?chuàng)建創(chuàng)建AudioContext對(duì)象。最簡(jiǎn)單的方法就像這樣:

var audioCtx = new AudioContext();

備注:雖然可以在一個(gè)document中創(chuàng)建多個(gè)AudioContext對(duì)象,但這恐怕沒什么卵用。

但是,Webkit/Blink內(nèi)核的瀏覽器不需要前綴,F(xiàn)irefox(desktop/mobile/OS)的瀏覽器可能需要前綴,所以為了兼容性考慮,最好寫成這樣:

var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
創(chuàng)建AudioSource

通過(guò)創(chuàng)建的AudioContext對(duì)象的方法,我們可以進(jìn)行各種各樣的操作。最初進(jìn)行的就是,準(zhǔn)備要播放的音源。下面列出的東西都可以作為音源:

使用震動(dòng)發(fā)聲器與JavaScript創(chuàng)建音源的情況:使用AudioContext.createOscillator這個(gè)方法創(chuàng)建OscillatorNode。之后就可以利用震動(dòng)發(fā)聲器做音源了。

使用原始的PCM數(shù)據(jù)的情況:如果是可以識(shí)別的特定的格式的話(mp3之類的),使用AudioContext的特定的decode方法,來(lái)獲得PCM數(shù)據(jù)。詳細(xì)情況可以看這些,AudioContext.createBuffer()、AudioContext.createBufferSource()、AudioContext.decodeAudioData() 。

使用

從WebRTC MediaStream(WebRTC媒體流)輸入音頻源的情況:可以使用麥克風(fēng)或者Web攝像頭。具體情況看這個(gè),AudioContext.createMediaStreamSource()

簡(jiǎn)單地把震動(dòng)發(fā)聲器作為音源,使用gain節(jié)點(diǎn)控制音量,這就構(gòu)成我我們接下來(lái)要說(shuō)的例子:

oscillator = audioCtx.createOscillator();
var gainNode = audioCtx.createGain();

備注:如果要播放音樂文件(mp3之類的),一般要利用XHR載入文件數(shù)據(jù),那之后創(chuàng)建BufferSource。在這個(gè)示例Voice-change-O-matic有代碼。

備注:Scott Michaud封裝了載入和解碼音頻的代碼,開源了一個(gè)庫(kù),叫AudioSampleLoader。使用這個(gè)的話,XHR以及buffer的操作都會(huì)變得異常簡(jiǎn)單。

輸入與輸出的連接

要想音源(輸入)通過(guò)揚(yáng)聲器(輸出)播放出來(lái),就必須要把兩者連接起來(lái)。將被連接的節(jié)點(diǎn)作為參數(shù),調(diào)用原來(lái)節(jié)點(diǎn)的的connect方法就可以建立節(jié)點(diǎn)間的連接。大多數(shù)類型的節(jié)點(diǎn)對(duì)象都擁有這個(gè)方法。

關(guān)于標(biāo)準(zhǔn)的輸出節(jié)點(diǎn)可以參考,AudioContext.destination。標(biāo)準(zhǔn)的輸出節(jié)點(diǎn)通常是設(shè)備的揚(yáng)聲器。把oscillator連接到gainNode上,gainNode的輸出連接到標(biāo)準(zhǔn)輸出上,代碼如下:

oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);

但如果像Voice-change-O-matic一樣,比較復(fù)雜的情況的話。需要像下面一樣將多個(gè)節(jié)點(diǎn)連接起來(lái),形成一張圖。:

source = audioCtx.createMediaStreamSource(stream);
source.connect(analyser);
analyser.connect(distortion);
distortion.connect(biquadFilter);
biquadFilter.connect(convolver);
convolver.connect(gainNode);
gainNode.connect(audioCtx.destination);

上面的代碼創(chuàng)建出的audio圖如下:

多個(gè)節(jié)點(diǎn)可以同時(shí)連接同一個(gè)節(jié)點(diǎn)。也可以讓多個(gè)音源通過(guò)一個(gè)效果節(jié)點(diǎn),達(dá)到混音的效果。

備注:Firefox 32 以上版本,在Firefox開發(fā)工具中Web Audio編輯器了。有了它之后大大提高了對(duì)audio節(jié)點(diǎn)圖進(jìn)行debug的效率。

播放與音調(diào)的設(shè)定

創(chuàng)建完audio節(jié)點(diǎn)圖后,就可以通過(guò)設(shè)定audio節(jié)點(diǎn)的屬性值或者調(diào)用方法來(lái)調(diào)整節(jié)點(diǎn)的效果。下面的例子,我們來(lái)設(shè)定下震動(dòng)發(fā)聲器的音調(diào),使用Hz這個(gè)單位,如下:

oscillator.type = 0; // sine wave,正弦波
oscillator.frequency.value = 2500; // value in hertz
oscillator.start();

在Violent Theremin這個(gè)程序中,設(shè)定了音量與周波數(shù)的最大值,如下:

var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;

var maxFreq = 6000;
var maxVol = 1;

var initialFreq = 3000;
var initialVol = 0.5;

// set options for the oscillator

oscillator.type = 0; // sine wave
oscillator.frequency.value = initialFreq; // value in hertz
oscillator.start();

gainNode.gain.value = initialVol;

加下來(lái)是隨著鼠標(biāo)的移動(dòng),按照設(shè)定改變周波數(shù)。鼠標(biāo)指針的X坐標(biāo)和Y坐標(biāo)以及周波數(shù)和音量的最大值,這些決定了最終輸出聲音的周波數(shù)和音量。代碼如下:

// Mouse pointer coordinates

var CurX;
var CurY;

// Get new mouse pointer coordinates when mouse is moved
// then set new gain and putch values

document.onmousemove = updatePage;

function updatePage(e) {   
    CurX = (window.Event) ? e.pageX : event.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
    CurY = (window.Event) ? e.pageY : event.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
    
    oscillator.frequency.value = (CurX/WIDTH) * maxFreq;
    gainNode.gain.value = (CurY/HEIGHT) * maxVol;

    canvasDraw();
}
利用Canvas實(shí)現(xiàn)簡(jiǎn)單的可視化效果

canvasDraw()是一個(gè)每次鼠標(biāo)移動(dòng)都會(huì)調(diào)用的方法。每次調(diào)用這個(gè)方法,都會(huì)在鼠標(biāo)指針位置所在的地方,把輸出音頻的周波數(shù)和音量用不同大小和不同顏色表現(xiàn)(畫)出來(lái)。

function random(number1,number2) {
  var randomNo = number1 + (Math.floor(Math.random() * (number2 - number1)) + 1);
  return randomNo;
}

var canvas = document.querySelector(".canvas");
canvas.width = WIDTH;
canvas.height = HEIGHT;

var canvasCtx = canvas.getContext("2d");

function canvasDraw() {
  rX = CurX;
  rY = CurY;
  rC = Math.floor((gainNode.gain.value/maxVol)*30);
 
  canvasCtx.globalAlpha = 0.2;
 
  for(i=1;i<=15;i=i+2) {
    canvasCtx.beginPath();
    canvasCtx.fillStyle = "rgb(" + 100+(i*10) + "," + Math.floor((gainNode.gain.value/maxVol)*255) + "," + Math.floor((oscillator.frequency.value/maxFreq)*255) + ")";
    canvasCtx.arc(rX+random(0,50),rY+random(0,50),rC/2+i,(Math.PI/180)*0,(Math.PI/180)*360,false);
    canvasCtx.fill();
    canvasCtx.closePath();     
  }    
}
靜音

按下靜音按鈕后,會(huì)執(zhí)行下面的函數(shù)。通過(guò)把Gain節(jié)點(diǎn)與前面連接的節(jié)點(diǎn)切斷,使得聲音的輸出消失。再按一次按鈕,就會(huì)恢復(fù)節(jié)點(diǎn)之間的連接,使得聲音恢復(fù)輸出。

var mute = document.querySelector(".mute");

mute.onclick = function() {
  if(mute.id == "") {
    gainNode.disconnect(audioCtx.destination);
    mute.id = "activated";
    mute.innerHTML = "Unmute";
  } else {
    gainNode.connect(audioCtx.destination);
    mute.id = "";    
    mute.innerHTML = "Mute";
  }
}
其他的節(jié)點(diǎn)

在 Web Audio API中其他還有很多的種類的節(jié)點(diǎn)可以使用。創(chuàng)建節(jié)點(diǎn)、節(jié)點(diǎn)與節(jié)點(diǎn)之間連接起來(lái),形成節(jié)點(diǎn)圖,之后通過(guò)屬性和方法來(lái)改變聲音。從這些點(diǎn)來(lái)看,所以節(jié)點(diǎn)的使用方式都差不多。

下面,我們概要地看一下幾個(gè)節(jié)點(diǎn)。各個(gè)節(jié)點(diǎn)的詳細(xì)情況可以在Web_Audio_API中看。

Wave shaper 節(jié)點(diǎn)

通過(guò)AudioContext.createWaveShaper這個(gè)方法,可以創(chuàng)建WaveShaper節(jié)點(diǎn)。

var distortion = audioCtx.createWaveShaper();

要想讓這個(gè)對(duì)象工作,必須給予與決定波形的函數(shù)。通過(guò)將這個(gè)函數(shù)應(yīng)用于輸入的波形,WaveShaper節(jié)點(diǎn)可以扭曲聲音。對(duì)新手來(lái)說(shuō),一開始寫出這個(gè)函數(shù)是很困難的吧。通過(guò)在網(wǎng)絡(luò)上搜索,選用合適的方案就好了。下面是一個(gè)發(fā)布在Stack Overflow上的例子:

function makeDistortionCurve(amount) {
  var k = typeof amount === "number" ? amount : 50,
    n_samples = 44100,
    curve = new Float32Array(n_samples),
    deg = Math.PI / 180,
    i = 0,
    x;
  for ( ; i < n_samples; ++i ) {
    x = i * 2 / n_samples - 1;
    curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );
  }
  return curve;
};

在Voice-Change-O-Metic這個(gè)例子中,創(chuàng)建了一個(gè)叫做distortion的WaveShaper節(jié)點(diǎn),提供了必要的音頻扭曲效果。代碼如下:

source.connect(analyser);
analyser.connect(distortion);
distortion.connect(biquadFilter);

...

distortion.curve = makeDistortionCurve(400);
雙二階過(guò)濾器

雙二階過(guò)濾器的內(nèi)部有多個(gè)配置項(xiàng)目。可以通過(guò)AudioContext.createBiquadFilter這個(gè)方法創(chuàng)建。

var biquadFilter = audioCtx.createBiquadFilter();

在Voice-Change-o-Metic這個(gè)例子中,使用的是典型的lowshelf 過(guò)濾器。這是為了提供一個(gè)基本的低音増幅效果:

biquadFilter.type = "lowshelf";
biquadFilter.frequency.value = 1000;
biquadFilter.gain.value = 25;

在這個(gè)例子中可以設(shè)定過(guò)濾器的種類,周波數(shù),甚至gain的值。如果是lowshelf過(guò)濾器的話,可以提供一個(gè)比指定周波數(shù)低25dB的低音増幅。

關(guān)于其他的Web Audio API的內(nèi)容

使用Web Audio API的話,可以做到音頻的可視化與立體化(例如音頻平移等)。關(guān)于這些,我們?cè)谄渌奈臋n中說(shuō)明。

后記

終于完了。

翻譯技術(shù)文章遠(yuǎn)比想象的要困難,特別是遇到很多陌生的某個(gè)領(lǐng)域下的專有詞匯。

日語(yǔ)真是神奇,很多硬是用片假名套英文的情況,呵呵呵,讓我想起了,特律風(fēng)。

文中不免有錯(cuò)的地方,希望大家能指出來(lái),幫助文章更好,謝謝。

感謝,@說(shuō)說(shuō)說(shuō)說(shuō)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/79643.html

相關(guān)文章

  • 絕對(duì)冷知識(shí),瀏覽器環(huán)境下JavaScript能夠利用到提交/請(qǐng)求數(shù)據(jù)方式有這么多!你都深入了解了

    摘要:你知道在瀏覽器環(huán)境下能夠利用到的提交請(qǐng)求數(shù)據(jù)的方式有哪些嗎這些方式各自有什么特點(diǎn)呢在什么情況下使用呢讓我們一起來(lái)整理一下。其實(shí)這也是能夠利用到的提交請(qǐng)求數(shù)據(jù)的方式之一。 你知道在瀏覽器環(huán)境下JavaScript能夠利用到的提交/請(qǐng)求數(shù)據(jù)的方式有哪些嗎?這些方式各自有什么特點(diǎn)呢?在什么情況下使用呢?讓我們一起來(lái)整理一下。 基礎(chǔ)知識(shí) 建議大家先看完這幾篇文章,了解一下基礎(chǔ)知識(shí) HTTP訪...

    bingchen 評(píng)論0 收藏0
  • 各種API+教程+練習(xí)

    摘要:做一個(gè)搬運(yùn)工,希望自己能努力學(xué)習(xí),也希望大神們的東西能讓更多的人看到不斷更新更新日志新增了網(wǎng)絡(luò)安全分類,整理了排版布局新增了的鏈接,將一些雜七雜八的東西弄到了一篇新文章上了,叫做積累與雜貨鋪一以及相關(guān)教程的規(guī)范與相關(guān)中文學(xué)習(xí)大本營(yíng)中文文檔簡(jiǎn) 做一個(gè)搬運(yùn)工,希望自己能努力學(xué)習(xí),也希望大神們的東西能讓更多的人看到 不斷更新 更新日志:2017.10.13 新增了網(wǎng)絡(luò)安全分類,整理了排版布局...

    saucxs 評(píng)論0 收藏0
  • 各種API+教程+練習(xí)

    摘要:做一個(gè)搬運(yùn)工,希望自己能努力學(xué)習(xí),也希望大神們的東西能讓更多的人看到不斷更新更新日志新增了網(wǎng)絡(luò)安全分類,整理了排版布局新增了的鏈接,將一些雜七雜八的東西弄到了一篇新文章上了,叫做積累與雜貨鋪一以及相關(guān)教程的規(guī)范與相關(guān)中文學(xué)習(xí)大本營(yíng)中文文檔簡(jiǎn) 做一個(gè)搬運(yùn)工,希望自己能努力學(xué)習(xí),也希望大神們的東西能讓更多的人看到 不斷更新 更新日志:2017.10.13 新增了網(wǎng)絡(luò)安全分類,整理了排版布局...

    20171112 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<