我想使用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.
你会看到你得到预期的波形,但“反转”(由于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>