JavaScript – Web音频API中的自定义波形

前端之家收集整理的这篇文章主要介绍了JavaScript – Web音频API中的自定义波形前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在通过这篇令人敬畏的文章https://jackschaedler.github.io/circles-sines-signals/dft_introduction.html

我想使用Web Audio API的PeriodicWave对象来实现这个演示:

但是,当我使用这些设置设置周期波时:

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

输出一个如下所示的波形:

这里是完整的代码http://jsbin.com/zaqojavixo/4/edit
要查看波形,请按播放声音几次.

我相信这些应该匹配,所以这里是我的问题:

我错过了这个理论的基本原理,还是我错误地实施了? PeriodicWave对象是否应该做同样的事情,如文章所示?
>如果我采取错误方法,我将如何在Web Audio API中实现该图?通过将不同频率的两个不同的正弦波连接到相同的增益节点,我已经能够匹配下面这个与使用PeriodicWave对象有什么不同?
>我是新的DSP和Web Audio API – 任何建议的阅读将不胜感激!
>其次,在我的示例中,我必须在正确的数据被绘制到画布之前先推动“播放声音”按钮 – 分析器似乎在振荡器的后面,尽管分析器.getFloatTimeDomainData()被调用我对这个发生了什么的启发振荡器呢?

编辑:如评论中所述,我的图形是颠倒的(在画布上,0是左上角).

解决方法

请注意,第一个数组定义了余弦项,第二个是正弦项:

The real parameter represents an array of cosine terms (traditionally
the A terms). In audio terminology,the first element (index 0) is the
DC-offset of the periodic waveform. The second element (index 1)
represents the fundamental frequency. The third element represents the
first overtone,and so on. The first element is ignored and
implementations must set it to zero internally.

The imag parameter represents an array of sine terms (traditionally
the B terms). The first element (index 0) should be set to zero (and
will be ignored) since this term does not exist in the Fourier series.
The second element (index 1) represents the fundamental frequency. The
third element represents the first overtone,and so on.

Source

你会看到你得到预期的波形,但“反转”(由于julian在他的答案中指出了这一点,颠倒了):

(我把你的代码放在这里,数组交换在:)
在原始代码中更新固定图纸问题

//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,-1,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,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>

猜你在找的JavaScript相关文章