2015-06-03 67 views
11

我通過這真棒文章的工作:https://jackschaedler.github.io/circles-sines-signals/dft_introduction.html自定義波形

我想利用網絡音頻API的PeriodicWave對象來實現這個演示:enter image description here

然而,當我設置週期波與這些設置:

var real = new Float32Array([0,0,1,0,1]); 
var imag = new Float32Array(real.length); 
var customWave = context.createPeriodicWave(real,imag); 
osc.setPeriodicWave(customWave); 

我輸出波看起來像這樣:

enter image description here 這裏是完整的代碼:http://jsbin.com/zaqojavixo/4/edit 要查看波形,請按數次播放聲音。

我相信這些應該投其所好,所以這裏是我的問題:

  1. 我失去了一些關於這裏的理論基礎還是我只是實現它是否有誤? PeriodicWave對象應該如文章所述做同樣的事情嗎?
  2. 如果我採取了錯誤的做法,我將如何在Web Audio API中實現此圖表?通過將不同頻率的兩個不同正弦波連接到相同的增益節點,我能夠進行匹配 - 這與使用PeriodicWave對象有什麼不同?
  3. 我是DSP和Web Audio API的新手 - 任何建議閱讀將不勝感激!其次,在我的例子中,在將正確的數據繪製到畫布之前,我必須推動'播放聲音'按鈕幾次 - 分析器似乎在振盪器後面,即使analyser.getFloatTimeDomainData()在我啓動振盪器後,在這裏發生了什麼?

編輯:正如在評論中指出,我的圖是倒掛(畫布0,0是左上角)。

回答

9

注意,第一陣列限定的餘弦項,第二正弦項:

real參數表示一組餘弦項(傳統上 的A條款)。在音頻術語中,第一個元素(索引0)是週期性波形的直流偏移量 。第二個元素(索引1) 代表基頻。第三個元素表示 第一個泛音,依此類推。第一個元素被忽略,實現必須在內部將其設置爲零。

imag參數表示的正弦項(傳統 的乙術語)的陣列。第一個元素(索引0)應該設置爲零(並且 將被忽略),因爲該項不存在於傅立葉級數中。 第二個元素(索引1)表示基頻。 第三個元素表示第一個泛音,依此類推。

Source

你會看到你會得到預期的波形,但「逆轉」(畫倒掛感謝@Julian指出這一點在他的答案 - 下面固定):

snap

(我在這裏用代碼替換了陣列:)
已更新原始代碼中的固定繪圖問題

//setup audio context 
 
window.AudioContext = window.AudioContext || window.webkitAudioContext; 
 
var context = new window.AudioContext(); 
 

 
//create nodes 
 
var osc; //create in event listener so we can press the button more than once 
 
var masterGain = context.createGain(); 
 
var analyser = context.createAnalyser(); 
 

 
//routing 
 
masterGain.connect(analyser); 
 
analyser.connect(context.destination); 
 

 
var isPlaying = false; 
 

 
//draw function for canvas 
 
function drawWave(analyser, ctx) { 
 
    
 
    var buffer = new Float32Array(1024), 
 
     w = ctx.canvas.width; 
 
    
 
    ctx.strokeStyle = "#777"; 
 
    ctx.setTransform(1,0,0,-1,0,100.5); // flip y-axis and translate to center 
 
    ctx.lineWidth = 2; 
 
    
 
    (function loop() { 
 
    analyser.getFloatTimeDomainData(buffer); 
 
    
 
    ctx.clearRect(0, -100, w, ctx.canvas.height); 
 

 
    ctx.beginPath(); 
 
    ctx.moveTo(0, buffer[0] * 90); 
 
    for (var x = 2; x < w; x += 2) ctx.lineTo(x, buffer[x] * 90); 
 
    ctx.stroke(); 
 
    
 
    if (isPlaying) requestAnimationFrame(loop) 
 
    })(); 
 
} 
 

 
//button trigger 
 
$(function() { 
 
    var c = document.getElementById('scope'), 
 
     ctx = c.getContext("2d"); 
 
    
 
    c.height = 200; 
 
    c.width = 600; 
 
    
 
    // make 0-line permanent as background 
 
    ctx.moveTo(0, 100.5); 
 
    ctx.lineTo(c.width, 100.5); 
 
    ctx.stroke(); 
 
    c.style.backgroundImage = "url(" + c.toDataURL() + ")"; 
 
    
 
    $('button').on('mousedown', function() { 
 
    osc = context.createOscillator(); 
 
    //osc settings 
 
    osc.frequency.value = 220; 
 
    var imag= new Float32Array([0,0,1,0,1]); // sine 
 
    var real = new Float32Array(imag.length); // cos 
 
    var customWave = context.createPeriodicWave(real, imag); // cos,sine 
 
    osc.setPeriodicWave(customWave); 
 

 
    osc.connect(masterGain); 
 
    osc.start(); 
 
    isPlaying = true; 
 
    
 
    drawWave(analyser, ctx); 
 
    }); 
 

 
    $('button').on('mouseup', function() { 
 
    isPlaying = false; 
 
    osc.stop(); 
 
    }); 
 
});
button {position:fixed;left:10px;top:10px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<button>Play the sound</button> 
 
<canvas id='scope'></canvas>

2

演示和輸出之間的唯一區別是兩個音調之間的相位關係。演示是y=sin(x) + sin(2x),你的是y=sin(x) + sin(2x + pi/2)。我並不清楚這個階段是從哪裏來的,但我不認爲這是你所做的任何事情。

下面是從鎢阿爾法一些圖:

y=sin(x) + sin(2x)

y=sin(x) + sin(2x + pi/2)

1

createPeriodicWavereal陣列是餘弦部分(或一個術語),而imag陣列(該b術語)是正弦部分。

參見:http://en.wikipedia.org/wiki/Fourier_series

我覺得你剛剛倒二。在它的文章中寫道:

其中Ai是第i個正弦的振幅,fi是第i個正弦的頻率。

所以它是你的imag數組(正弦部分)應該是[0,0,1,0,1],你的真實數組應該是[0,0,0,0,0]。

像這樣:

var imag = new Float32Array([0,0,1,0,1]); 
var real = new Float32Array(real.length); 

嘗試在你的jsbin你將它的作品,唯一的事情,它會被反轉,因爲你是在否定繪畫(意爲0座標的頂部,而不是底部)。要獲得文章中的內容,請反向繪製或使用您的imag數組:[0,0,-1,0,-1]。

如果你要玩一點不同imagreal配置並查看結果,你可以在這裏看到:http://themusictoolbox.net/waves/