Javascript Webaudio同时播放两个振荡器声音会导致振动声音
使用网络音频,我产生了一种声音,但听起来很糟糕(振动)。如果我使用非常低的增益,那就更好了,但是太安静了。与使用具有非常低值的低通滤波器相同。在同一时间播放多个频率的正确方法是什么 您可以看到,单击“播放1”按钮可以获得“A”注释。 “播放2”按钮适用于“C”音符。 当两个按钮同时播放时,“播放两个”按钮听起来很糟糕Javascript Webaudio同时播放两个振荡器声音会导致振动声音,javascript,web-audio-api,Javascript,Web Audio Api,使用网络音频,我产生了一种声音,但听起来很糟糕(振动)。如果我使用非常低的增益,那就更好了,但是太安静了。与使用具有非常低值的低通滤波器相同。在同一时间播放多个频率的正确方法是什么 您可以看到,单击“播放1”按钮可以获得“A”注释。 “播放2”按钮适用于“C”音符。 当两个按钮同时播放时,“播放两个”按钮听起来很糟糕 <html> <head> <title>Audio</title> <script&
<html>
<head>
<title>Audio</title>
<script>
var context = null;
var oscillatorNode1 = null;
var oscillatorNode2 = null;
function stop() {
if ( oscillatorNode1 != null ) {
oscillatorNode1.stop(context.currentTime);
oscillatorNode1 = null;
}
if ( oscillatorNode2 != null ) {
oscillatorNode2.stop(context.currentTime);
oscillatorNode2 = null;
}
}
function play1() {
stop();
if ( context === null) {
context = new AudioContext();
}
oscillatorNode1 = context.createOscillator();
oscillatorNode1.type = 'sine';
oscillatorNode1.frequency.value = 220;
oscillatorNode1.connect(context.destination);
oscillatorNode1.start();
oscillatorNode2 = context.createOscillator();
oscillatorNode2.type = 'sine';
oscillatorNode2.frequency.value = 261.6255653005986;
oscillatorNode2.connect(context.destination);
oscillatorNode2.start();
}
function play2() {
stop();
if ( context === null) {
context = new AudioContext();
}
oscillatorNode1 = context.createOscillator();
oscillatorNode1.type = 'sine';
oscillatorNode1.frequency.value = 220;
oscillatorNode1.connect(context.destination);
oscillatorNode1.start();
}
function play3() {
stop();
if ( context === null) {
context = new AudioContext();
}
oscillatorNode2 = context.createOscillator();
oscillatorNode2.type = 'sine';
oscillatorNode2.frequency.value = 261.6255653005986;
oscillatorNode2.connect(context.destination);
oscillatorNode2.start();
}
</script>
</head>
<body>
<form>
<input type="button" onclick="play1()" value="Play both" />
<input type="button" onclick="play2()" value="Play 1" />
<input type="button" onclick="play3()" value="Play 2" />
<input type="button" onclick="stop()" value="Stop" />
</form>
</body>
</html>
音频
var-context=null;
var oscillatorNode1=零;
var oscillatorNode2=零;
函数停止(){
如果(振荡模式1!=null){
振荡模式1.停止(context.currentTime);
振荡器NODE1=零;
}
如果(振荡模式2!=null){
振荡模式2.停止(context.currentTime);
振荡器NODE2=零;
}
}
函数play1(){
停止();
如果(上下文===null){
上下文=新的AudioContext();
}
oscillatorNode1=context.createOscillator();
oscillatorNode1.type='sine';
振荡器NODE1.frequency.value=220;
连接(context.destination);
oscillatorNode1.start();
oscillatorNode2=context.createOscillator();
oscillatorNode2.type='sine';
振荡器NODE2.frequency.value=261.6255653050986;
连接(context.destination);
oscillatorNode2.start();
}
函数play2(){
停止();
如果(上下文===null){
上下文=新的AudioContext();
}
oscillatorNode1=context.createOscillator();
oscillatorNode1.type='sine';
振荡器NODE1.frequency.value=220;
连接(context.destination);
oscillatorNode1.start();
}
函数play3(){
停止();
如果(上下文===null){
上下文=新的AudioContext();
}
oscillatorNode2=context.createOscillator();
oscillatorNode2.type='sine';
振荡器NODE2.frequency.value=261.6255653050986;
连接(context.destination);
oscillatorNode2.start();
}
我猜您描述的振动是由剪切引起的。当两个振荡器同时演奏时,可能分别产生+2或-2的值。将以下代码段粘贴到的编辑器中时,可以直观地看到它
可以通过添加值为0.5
的GainNode来避免这种情况。然而,组合信号将被视为纯音,稍微安静一些。这是因为纯音总是在+1和-1之间交替,而组合音并不总是达到极值
添加GainNode后,play1()
函数的核心部分在某种程度上如下所示:
oscillatorNode1 = context.createOscillator();
oscillatorNode1.frequency.value = 220;
oscillatorNode2 = context.createOscillator();
oscillatorNode2.frequency.value = 261.6255653005986;
gainNode = context.createGain();
gainNode.gain.value = 0.5;
oscillatorNode1.connect(gainNode);
oscillatorNode2.connect(gainNode);
gainNode.connect(context.destination);
oscillatorNode1.start();
oscillatorNode2.start();
这与数字音频和音频工程有很大关系 你肯定想把音量调低。考虑不同的声音:把较少的工作放在单独的扬声器上会发出更清晰的声音。 我几乎同时使用了几十个振荡器。我制作的这个应用让你疯狂吧。以下是两个振荡器的示例: 使用我上面提到的“立体声”概念,我使用context.createchannelmerge,然后将每个正弦波连接到每个输出通道,效果非常好。 它似乎在一对扬声器上比在另一对扬声器上工作得更好。这在电话里不太管用。然而,加上增益使它在我测试过的所有扬声器和手机上都非常好。我仍然希望有一个很好的解决方案来合并这些,使之听起来像真正的空气合并 我还试着把更新后的代码粘贴到树冠上,但听起来不太好。一个原因是音频上下文已经创建,创建一个新的上下文效果很好。因此,现有的一个在该页面上不能很好地工作
context = new AudioContext();
oscillatorNode1 = context.createOscillator();
oscillatorNode1.type = 'sine';
oscillatorNode1.frequency.value = 220;
var merger = context.createChannelMerger(2);
merger.connect(context.destination);
oscillatorNode1.connect(merger, 0, 0);
oscillatorNode1.start();
oscillatorNode2 = context.createOscillator();
oscillatorNode2.type = 'sine';
oscillatorNode2.frequency.value = 261.6255653005986;
oscillatorNode2.connect(merger, 0, 1);
oscillatorNode2.start();
我在上面提到,增加低增益会有所帮助,但并不能解决这个问题。您的增益示例代码也没有修复它,它有帮助。添加具有非常低值的低通滤波器似乎可行,但非常安静,因此基本上增益非常小。谢谢你的帮助。为每个振荡器创建一个增益节点。@vdu在这种情况下,我误解了这个问题。我认为您可能使用了高于0.5的增益值,因为您说它会产生非常安静的信号。如果低通滤波器有帮助的话,我想你所说的振动就是叠加两个正弦波所产生的伪影。我不确定到底是什么帮助解决了这个问题。这是非常主观的。如果你想保留纯音的声音,你可以在其他两个音调之间的频率播放一个振荡器,而不是叠加两个振荡器。@MikeHelland两种方法的声音应该相同。Web音频API中没有内部剪辑。至少只要这些数字保持在JavaScript可表示的范围内,就不会发生变化。:-)@chrisguttandin在试验叠加两个正弦波的效果时,我用上面的测试打开了两个浏览器窗口。然后,我在每个屏幕上播放一个声音,结果是一样的。我尝试了Chrome和Firefox,结果都一样。但是,当在电脑上播放1个声音(播放1)和在我手机的扬声器手机上播放另一个声音(播放2)并更改两者的音量以匹配时,声音正常。你可以轻松一下
context = new AudioContext();
oscillatorNode1 = context.createOscillator();
oscillatorNode1.type = 'sine';
oscillatorNode1.frequency.value = 220;
var merger = context.createChannelMerger(2);
merger.connect(context.destination);
oscillatorNode1.connect(merger, 0, 0);
oscillatorNode1.start();
oscillatorNode2 = context.createOscillator();
oscillatorNode2.type = 'sine';
oscillatorNode2.frequency.value = 261.6255653005986;
oscillatorNode2.connect(merger, 0, 1);
oscillatorNode2.start();