Javascript web音频API中的自定义波形
我正在阅读这篇很棒的文章: 我想使用Web Audio API的PeriodicWave对象来实现此演示: 但是,当我使用以下设置设置周期波时:Javascript web音频API中的自定义波形,javascript,audio,signal-processing,web-audio-api,Javascript,Audio,Signal Processing,Web Audio Api,我正在阅读这篇很棒的文章: 我想使用Web Audio API的PeriodicWave对象来实现此演示: 但是,当我使用以下设置设置周期波时: var real = new Float32Array([0,0,1,0,1]); var imag = new Float32Array(real.length); var customWave = context.createPeriodicWave(real,imag); osc.setPeriodicWave(customWave);
var real = new Float32Array([0,0,1,0,1]);
var imag = new Float32Array(real.length);
var customWave = context.createPeriodicWave(real,imag);
osc.setPeriodicWave(customWave);
我输出的波形如下所示:
以下是完整代码:
要查看波形,请按几次播放声音
我相信这些应该是匹配的,所以我的问题如下:
编辑:如注释中所述,我的图形是颠倒的(在画布上,0,0是左上角) 演示和输出之间的唯一区别是两个音调之间的相位关系。演示是
y=sin(x)+sin(2x)
,你的演示是y=sin(x)+sin(2x+pi/2)
。我不清楚这个相移是从哪里来的,但我不认为你做了什么
以下是wolfram alpha的一些图:
请注意,第一个数组定义余弦项,第二个数组定义正弦项:
real
参数表示余弦项的数组
第二部分(A条款)。在音频术语中,第一个元素(索引0)是
周期波形的直流偏移。第二个元素(索引1)
表示基频。第三个元素表示
第一泛音,等等。第一个元素被忽略,并且
实现必须在内部将其设置为零
imag
参数表示正弦项的数组
(B)条款)。第一个元素(索引0)应设置为零(和
将被忽略),因为该项在傅里叶级数中不存在。
第二个元素(索引1)表示基频。这个
第三个元素代表第一泛音,依此类推
您将看到,您得到了预期的波形,但“反转”(由于@Julian在其答案中指出了这一点,因此画得颠倒-固定如下):
(我在这里内联了您的代码,并交换了阵列:)更新了修复了原始代码中的图纸问题
//设置音频上下文
window.AudioContext=window.AudioContext | | window.webkitadiocontext;
var context=new window.AudioContext();
//创建节点
var-osc//创建事件侦听器,以便我们可以多次按下按钮
var masterGain=context.createGain();
var analyzer=context.createanalyzer();
//路由
主增益连接(分析仪);
分析器.连接(上下文.目的地);
var显示=假;
//画布的绘制功能
函数drawWave(分析仪,ctx){
var buffer=new Float32Array(1024),
w=ctx.canvas.width;
ctx.strokeStyle=“#777”;
ctx.setTransform(1,0,0,-1,0100.5);//翻转y轴并平移到中心
ctx.lineWidth=2;
(函数循环(){
Analyzer.getFloatTimeDomainData(缓冲区);
ctx.clearRect(0,-100,w,ctx.canvas.height);
ctx.beginPath();
ctx.moveTo(0,缓冲区[0]*90);
对于(var x=2;x
按钮{位置:固定;左侧:10px;顶部:10px}
播放声音
在createPeriodicWave
中,real
数组是余弦部分(或a项),而imag
数组(b项)是正弦部分
见:
我想你刚刚把两者颠倒过来了。文章中说:
式中,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]
如果您想使用不同的imag
和real
配置玩一玩,并查看结果,您可以在这里看到:感谢您分享这张漂亮的wave渲染图!